[英]How to detect orientation change in layout in Android?
我刚刚实现了一个方向更改功能 - 例如,当布局从纵向变为横向(反之亦然)时。 如何检测方向更改事件何时完成。
OrientationEventListener
不起作用。 如何获得有关布局方向更改事件的通知?
使用 Activity 的onConfigurationChanged方法。 请参阅以下代码:
@Override
public void onConfigurationChanged(@NotNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
您还必须编辑适当的清单文件中的元素以包含android:configChanges只需查看以下代码:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
注意:对于 Android 3.2(API 级别 13)或更高版本,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。 因此,如果您想在为 API 级别 13 或更高级别开发时防止由于方向更改而导致运行时重新启动,则必须为 API 级别 13 或更高级别声明android:configChanges="orientation|screenSize" 。
希望能帮到你... :)
要在layout-land文件夹中加载布局意味着您有两个单独的布局,那么您必须在onConfigurationChanged
方法中创建setContentView
。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.yourxmlinlayout-land);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.yourxmlinlayoutfolder);
}
}
如果您只有一种布局,则无需在此方法中设置 setContentView。 简单地
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
只是想向您展示一种在 onConfigurationChanged 后保存所有 Bundle 的方法:
课程结束后创建新的 Bundle:
public class MainActivity extends Activity {
Bundle newBundy = new Bundle();
接下来,在“protected void onCreate”之后添加:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
onSaveInstanceState(newBundy);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
onSaveInstanceState(newBundy);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBundle("newBundy", newBundy);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getBundle("newBundy");
}
如果您将其添加到 MainActivity 中,您所有的 crated 类都将被保存。
但最好的方法是在你的 AndroidManifest 中添加这个:
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
使用这个方法
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
{
Toast.makeText(getActivity(),"PORTRAIT",Toast.LENGTH_LONG).show();
//add your code what you want to do when screen on PORTRAIT MODE
}
else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
Toast.makeText(getActivity(),"LANDSCAPE",Toast.LENGTH_LONG).show();
//add your code what you want to do when screen on LANDSCAPE MODE
}
}
并且不要忘记在您的 Androidmainfest.xml 中添加它
android:configChanges="orientation|screenSize"
像这样
<activity android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:configChanges="orientation|screenSize">
</activity>
如果这对一些较新的开发人员有用,因为上面没有指定。 只是要非常明确:
如果使用onConfigurationChanged ,您需要做两件事:
Activity 类中的onConfigurationChanged
方法
在清单中指定onConfigurationChanged
方法将处理哪些配置更改
清单片段在上面的答案,而无疑是正确的特定应用程序,明显属于,不正是你需要在你的清单中添加,以触发您的活动课的onConfigurationChanged方法是什么。 即以下清单条目可能不适合您的应用程序。
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
在上面的清单条目中, android:configChanges=""
有各种 Android 操作,它们可以在您的 Activity 生命周期中触发 onCreate。
这非常重要 -清单中未指定的是触发您的 onCreate的那些,清单中指定的是触发您的活动类中的onConfigurationChanged
方法的那些。
因此,您需要确定需要自己处理哪些配置更改。 对于像我这样的 Android Encyclopedically Challenged,我使用了 Android Studio 中的快速提示弹出窗口,并添加了几乎所有可能的配置选项。 列出所有这些基本上是说我会处理所有事情,并且由于配置,永远不会调用 onCreate。
<activity name= ".MainActivity" android:configChanges="screenLayout|touchscreen|mnc|mcc|density|uiMode|fontScale|orientation|keyboard|layoutDirection|locale|navigation|smallestScreenSize|keyboardHidden|colorMode|screenSize"/>
现在显然我不想处理所有事情,所以我开始一次消除上述选项。 每次删除后重新构建和测试我的应用程序。
另一个重点:如果只有一个配置选项被自动处理触发您的 onCreate(您没有在上面的清单中列出它),那么它看起来就像onConfigurationChanged
不起作用。 您必须将所有相关的放入您的清单中。
我最终得到了 3 个最初触发 onCreate 的结果,然后我在 S10+ 上进行了测试,我仍然得到了 onCreate,所以我不得不再次进行消除练习,而且我还需要|screenSize
。 因此,在选择的平台上进行测试。
<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/>
所以我的建议,虽然我确信有人可以在这方面戳破洞:
使用 TOAST 或 LOG 在您的活动类中添加您的onConfigurationChanged
方法,以便您可以看到它何时工作。
将所有可能的配置选项添加到您的清单中。
通过测试您的应用程序来确认您的onConfigurationChanged
方法正在运行。
一次从清单文件中删除每个配置选项,并在每个选项之后测试您的应用程序。
在尽可能多的设备上进行测试。
不要将我上面的代码片段复制/粘贴到您的清单文件中。 Android 更新会更改列表,因此请使用弹出的 Android Studio 提示确保您获得所有提示。
我希望这可以节省一些时间。
我的onConfigurationChanged
方法仅用于以下信息。 onConfigurationChanged
被称为生命周期后,新的方向是可用的,但在此之前的UI已创建。 因此,我的第一个if
检查方向是否正常工作,然后第二个嵌套if
查看我的 UI ImageView 的可见性也正常工作。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
}
}
覆盖活动的方法onConfigurationChanged
我只是想提出另一种替代方案,确实会引起你们中的一些人的关注,正如上面所解释的:
android:configChanges="orientation|keyboardHidden"
意味着我们明确声明要注入的布局。
如果我们想通过 layout-land 和 layout 文件夹保持自动注入。 您所要做的就是将其添加到 onCreate 中:
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
getSupportActionBar().hide();
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
getSupportActionBar().show();
}
在这里,我们根据手机的方向显示或不显示操作栏
创建OrientationEventListener
类的实例并启用它。
OrientationEventListener mOrientationEventListener = new OrientationEventListener(YourActivity.this) {
@Override
public void onOrientationChanged(int orientation) {
Log.d(TAG,"orientation = " + orientation);
}
};
if (mOrientationEventListener.canDetectOrientation())
mOrientationEventListener.enable();
如果接受的答案对您不起作用,请确保您没有在清单文件中定义:
android:screenOrientation="portrait"
这是我的情况。
以最简单的形式实现 Kotilin - 仅在屏幕从纵向 <--> 横向变化时触发,如果需要设备翻转检测(180 度),您需要标记重力传感器值
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rotation = windowManager.defaultDisplay.rotation
when (rotation) {
0 -> Log.d(TAG,"at zero degree")
1 -> Log.d(TAG,"at 270 degree")
2 -> Log.d(TAG,"at 180 degree")
3 -> Log.d(TAG,"at 90 degree")
}
}
如果其他人像我一样在这方面花费太长时间 - 它在模拟器上不起作用。 必须是真机。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.