Anroid Activity方向锁定及其横竖屏切换

98 篇文章 2 订阅

最近用到了视频组件,需要设置横竖屏,所以现在把基础知识再梳理一下.

最简单的一句话搞横竖屏:
在AndroidManifest.xml中静态声明设置Activity的方向参数:

android:screenOrientation="portrait" //设置竖屏
android:screenOrientation="landscape"//横屏
android:screenOrientation="sensor"//根据传感器
android:screenOrientation="behind"//根据栈中前一个Activity方向保持一致
//还有更多,不常用,不过可以看出Android横竖屏切换搞出这么属性.还是很强大的;
/*
     * The preferred screen orientation this activity would like to run in.
     * From the {@link android.R.attr#screenOrientation} attribute, one of
     * {@link #SCREEN_ORIENTATION_UNSPECIFIED},
     * {@link #SCREEN_ORIENTATION_LANDSCAPE},
     * {@link #SCREEN_ORIENTATION_PORTRAIT},
     * {@link #SCREEN_ORIENTATION_USER},
     * {@link #SCREEN_ORIENTATION_BEHIND},
     * {@link #SCREEN_ORIENTATION_SENSOR},
     * {@link #SCREEN_ORIENTATION_NOSENSOR},
     * {@link #SCREEN_ORIENTATION_SENSOR_LANDSCAPE},
     * {@link #SCREEN_ORIENTATION_SENSOR_PORTRAIT},
     * {@link #SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
     * {@link #SCREEN_ORIENTATION_REVERSE_PORTRAIT},
     * {@link #SCREEN_ORIENTATION_FULL_SENSOR},
     * {@link #SCREEN_ORIENTATION_USER_LANDSCAPE},
     * {@link #SCREEN_ORIENTATION_USER_PORTRAIT},
     * {@link #SCREEN_ORIENTATION_FULL_USER},
     * {@link #SCREEN_ORIENTATION_LOCKED},
     */

上述代码,需要在activity 标签上使用

<activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar">

        </activity>

或者使用Java代码设置:

//获取设备当前方向
int currentO = getResources().getConfiguration().orientation;
//强制设置为横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//强制设置竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);

需要注意是切换屏幕,不会保持默认的Activity的生命周期,发生变化时,Activity会被销毁重新创建.这通常会损失应用的性能,因此需要先保持UI状态,然后重建Activity.
解决这个重建问题需要
在AndroidManifest.xml 给Activity设置

android:configChanges="orientation|keyboardHidden"

orientation参数注册了设备方向变动的事件, keyboardHidden为键盘事件,需要一并设置,否则Activity也可能会在这些事件上导致重建.

一次从竖屏-横屏-竖屏的生命周期变化如下:

11-07 22:58:55.364 11537-11537/...MainActivity: onCreate
11-07 22:58:55.364 11537-11537/...MainActivity: onResume()
11-07 22:59:00.364 11537-11537/...MainActivity: onPause()
11-07 22:59:00.374 11537-11537/...MainActivity: onStop
11-07 22:59:00.374 11537-11537/...MainActivity: onDestroy()
11-07 22:59:00.484 11537-11537/...MainActivity: onCreate
11-07 22:59:00.494 11537-11537/...MainActivity: onResume()
11-07 22:59:04.154 11537-11537/...MainActivity: onPause()
11-07 22:59:04.154 11537-11537/...MainActivity: onStop
11-07 22:59:04.154 11537-11537/...MainActivity: onDestroy()
11-07 22:59:04.224 11537-11537/...MainActivity: onCreate
11-07 22:59:04.224 11537-11537/...MainActivity: onResume()

因此,我们需要在配置发生变化时,保存必要地数据,然后重新加载视图资源;
类似下面的伪代码:

@Override
protected void onCreate(Bundle b){
    super.onCreate(b);
    loadView();
}
...
@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    saveState();
    loadView(); 
}

public void saveState(){} //保存必要数据
public void loadView(){
    setContentView(R.layout.main);
    //根据新的变化,处理其他必要地UI改动
    //恢复和保存的状态

}

写了这么多,但是Google说不建议这样使用…网上也很多方法说这么设置;
但是按照上述设置,我试过,我发现Acitvity的生命周期onConfigurationChanged并未调用;⊙﹏⊙b汗


后记:
至此困扰我将近两天的问题,Activity_A竖屏跳转Activity_B横屏,再finsh回到A,则A发生重建,为了不让A创建.用尽了网上千篇一律的解决方法都没有解决,
如果把xml的设置. 设置成

android:configChanges="orientation|screenSize"

然后,再看看看横竖屏切换时,Activity的生命周期变化:

11-07 23:18:17.104 ......MainActivity: onCreate
11-07 23:18:17.104 ......MainActivity: onResume()
11-07 23:18:21.704 ......MainActivity: onConfigurationChanged:2
11-07 23:18:26.134 ......MainActivity: onConfigurationChanged:1
11-07 23:18:28.884 ......MainActivity: onConfigurationChanged:2
11-07 23:18:33.184 ......MainActivity: onConfigurationChanged:1

从实践的数据(机型:Mi3Cmiui7)由此看见,Activity并没有发生,不需要那么麻烦手动保存数据什么的.
没想到一个参数就搞定了.
另外,
如果是为了在发生横竖屏切换时,Ui需要重新布局,则可添加横屏竖屏的xml布局,如res/layout-land;这样Android会寻找其目录下的资源;
重要的参数再说一遍:

android:configChanges="orientation|screenSize|keyboardHidden"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值