Answers:
使用Activity 的onConfigurationChanged方法。请参阅以下代码:
@Override
public void onConfigurationChanged(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文件夹中,意味着您有两个单独的布局,然后必须使用setContentViewin onConfigurationChanged方法。
@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(Configuration newConfig)方法(如本答案所示),但是我没有自己处理它,而是设置了一个Boolean标志,然后调用该recreate()方法,以便Android以正常方式重新创建活动。
recreate()方法的一个问题是它导致屏幕短暂闪烁黑色。因此,我使用了另一种方法:(1)将屏幕宽度保存在中onCreate(...),(2)在活动终止时(例如onSaveInstanceState(...)),以任何生命周期方法将保存的屏幕宽度与当前屏幕宽度进行比较。
只是想向您展示一种在onConfigurationChanged之后保存所有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中。
但是最好的方法是在AndroidManifest中添加以下代码:
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
onConfigurationChanged(),您的instanceState不会在方向更改时被销毁,因此您不必保存它。您可能希望将其保存为活动生命周期中的其他事件,但我不知道。
使用这种方法
@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
如上所述,事实上,我只想提出另一个与您有关的替代方法:
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();
如果这对某些较新的开发人员有用,因为上面没有指定。只是非常明确:
如果使用onConfigurationChanged,则需要两件事:
onConfigurationChanged您的Activity类中的方法
在清单中指定将由您的onConfigurationChanged方法处理的配置更改
清单片段在上面的答案,而无疑是正确的特定应用程序,明显属于,是不是正是你需要在添加什么您的清单来触发你的活动课的onConfigurationChanged方法。即,以下清单条目可能不适用于您的应用。
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
在上述清单条目中,有各种Android操作android:configChanges=""可以触发您的Activity生命周期中的onCreate。
这非常重要- 清单中未指定的那些触发您的onCreate,清单中指定的那些触发您onConfigurationChanged的Activity类中的方法。
因此,您需要确定需要处理的配置更改。对于像我这样的Android百科全书挑战者,我使用了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"/>
因此,我的建议是,尽管我确定有人可以在此戳破漏洞:
onConfigurationChanged使用TOAST或LOG在活动类中添加方法,以便查看其工作时间。
将所有可能的配置选项添加到清单中。
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);
}
}
}
以最简单的形式实现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")
}
}