Android 开发横竖屏切换

1,306 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

开发中,时常会遇到横竖屏的切换问题

在清单文件中的android:screenOrientation属性,是控制横屏竖屏的方向

一、最常见的是下面两种:

  • landscape 横屏方向,显示的宽比高长
  • portrait 竖屏方向,显示的高比宽长

二、用法如下图,直接在清单文件中选择固定方向:

1669882851002(1).jpg

其他属性:

描述
unspecified默认值。系统自动选择屏幕方向
behind跟activity堆栈中的下面一个activity的方向一致
landscape横屏方向,显示的宽比高长
portrait竖屏方向,显示的高比宽长
sensor由设备的物理方向传感器决定,如果用户旋转设备,这屏幕就会横竖屏切换
nosensor忽略物理方向传感器,这样就不会随着用户旋转设备而横竖屏切换了("unspecified"设置除外)
user用户当前首选的方向
reversePortraitAPI 9 以上,反向竖屏
sensorLandscapeAPI 9 以上,横屏,但是可以根据 物理方向传感器来切换正反向横屏
sensorPortraitAPI 9 以上,竖屏,但是可以根据 物理方向传感器来切换正反向竖屏
fullSensorAPI 9 以上,上下左右四个方向,由物理方向传感器决定
lockedAPI 18 以上,锁死当前屏幕的方向
-------------------------

三、如果横竖屏切换,会受到的影响

  • 1、activity生命周期问题

    横竖屏切换时会先销毁相应activity,后在创建横屏或竖屏的activity,因此生命周期为onPause-> onStop-> onDestory-> onCreate->onStart->onResume; 此时如果如果有layout-land下的activity布局时横竖屏切换时会使用不同的布局xml文件。

如果不想让activity重新创建时在manifest的activity节点处添加属性:

 android:configChanges="orientation|screenSize"
  • 2.自动切换时布局问题

    横竖屏切换时如果重新创建了activity会重新加载相应的布局文件(layout下的或者layout-land下的),但如果设置了configChanges="orientation|screenSize"由于不会重新创建activity所以布局只会使用竖屏的布局文件。 屏幕方向变化之后会回调activity或者fragment的onConfigurationChanged方法。

此时如果想要适配横竖屏: 1.可在onConfigurationChanged中重新设置下contentview:

//1.布局分别在layout-land和layout-port目录中的同名main.xml时
@Override
public void onConfigurationChanged (Configuration newConfig){
   super.onConfigurationChanged(newConfig);
   setContentView(R.layout.main);
   //注意,这里删除了init(),否则又初始化了,状态就丢失
   findViews();
   setListensers();
}


//2.布局为不按照layout-land和layout-port目录,而自定义名字时
@Override
public void onConfigurationChanged (Configuration newConfig){
   super.onConfigurationChanged(newConfig);
   int mCurrentOrientation = getResources().getConfiguration().orientation;
   if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ) {
       // If current screen is portrait
       setContentView(R.layout.mainP);
       //注意,这里删除了init(),否则又初始化了,状态就丢失
       findViews();
       setListensers();
   } else if ( mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE ) {
       //If current screen is landscape
       setContentView(R.layout.mainL);
       //注意,这里删除了init(),否则又初始化了,状态就丢失
       findViews();
       setListensers();
   }
}
  • 以上是总结,希望能帮到你