Android屏幕旋转之横屏竖屏切换的实现
刚实现了App内手机横/竖放置时,屏幕横/竖屏的切换。记录一下中间需要的关键信息和实现过程。
开门见山的说,实现屏幕自动/手动旋转的方式有两种:
一种是在工程的代码中定义,这种方式在横竖屏切换时执行的操作是:销毁当前Activity–根据新的屏幕尺寸重建Activity。如果不进行数据存储的操作,在切换的过程中Activity中的数据会丢失。
另一种是在工程的AndroidManifest.xml中定义,这种定义的方式在某些情况下可以实现“不销毁需要横竖屏的Activity”,因为这种方式不会销毁Activity后重建Activity,因此Activity的数据不会丢失。
接下来分别介绍这两种实现方式:
方式一:代码中定义
在需要横屏的Activity中的onCreate方法内添加如下语句,并且要求该语句位于onCreate方法内setContentView(**)语句之前。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
上条语句中,常数SCREEN_ORIENTATION_FULL_SENSOR是决定屏幕如何旋转的参数。总结所有的参数对应的功能:
参数 |
功能 |
---|---|
SCREEN_ORIENTATION_BEHIND |
继承Activity堆栈中当前Activity下面的那个Activity的方向 |
SCREEN_ORIENTATION_FULL_SENSOR |
由重力传感器决定0/90/180/270° |
SCREEN_ORIENTATION_FULL_USER |
|
SCREEN_ORIENTATION_LANDSCAPE |
始终横屏 |
SCREEN_ORIENTATION_PORTRAIT |
始终竖屏 |
SCREEN_ORIENTATION_LOCKED |
锁定屏幕方向 |
SCREEN_ORIENTATION_NOSENSOR |
关闭重力传感器对横/竖屏的影响 |
SCREEN_ORIENTATION_REVERSE_LANDSCAPE |
另一个方向的横屏 |
SCREEN_ORIENTATION_REVERSE_PORTRAIT |
另一个方向的竖屏(倒拿手机) |
SCREEN_ORIENTATION_SENSOR |
重力传感器影响屏幕的方向0/90/270° |
SCREEN_ORIENTATION_SENSOR_LANDSCAPE |
始终横屏,由重力传感器决定是哪个方向的横屏 |
SCREEN_ORIENTATION_SENSOR_PORTRAIT |
始终竖屏,由重力传感器决定是哪个方向的竖屏 |
SCREEN_ORIENTATION_UNSPECIFIED |
不指定方向,使用默认方向 |
SCREEN_ORIENTATION_USER |
由用户和重力传感器共同决定,详见文本末端 |
SCREEN_ORIENTATION_USER_LANDSCAPE |
用户和重力传感器共同决定是哪个方向的横屏 |
SCREEN_ORIENTATION_USER_PORTRAIT |
用户和重力传感器共同决定是哪个方向的竖屏 |
UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW |
当屏幕较窄时导航栏有一部分会显示在底部 |
由于该方式下横/竖屏切换时,对应的Activity的数据会丢失,可以在对应的Activity中重写如下两个方法,来保证数据不丢失:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//横竖屏切换前调用,保存用户想要保存的数据,以下是样例
outState.putString("name","yoosir");
outState.putInt("age",24);
outState.putBoolean("handsome",true);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 屏幕切换完毕后调用用户存储的数据,以下为样例:
if(savedInstanceState != null) {
int age = savedInstanceState.getInt("age");
String name = savedInstanceState.getString("name");
boolean isHandsome = savedInstanceState.getBoolean("handsome");
}
}
方式二:在AndroidManifest.xml中定义
在AndroidManifest.xml中对应的Activity属性定义中配置android:configChanges和screenOrientation。参考的文章中在android:configChanges的配置说的很清楚,我直接把结论贴出来:
android:configChanges="orientation|keyboardHidden|screenSize"
- 配置configChanges为以上配置时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。Activity中的数据不会被销毁。
- 不配置configChanges或配置configChanges为非以上配置时,切屏会重新调用当前Activity的各个生命周期。Activity中的数据会被销毁。
给出示例代码如下:
<activity android:name=".com.cdsn.SearchActivity"
... ...
android:screenOrientation="sensor"
android:configChanges="keyboardHidden|orientation|screenSize"
/
上述代码中的android:screenOrientation所有可能的参数配置如下 。
值 |
描述 |
---|---|
unspecified |
默认值。系统自动选择屏幕方向 |
behind |
跟activity堆栈中的下面一个activity的方向一致 |
landscape |
横屏方向,显示的宽比高长 |
portrait |
竖屏方向,显示的高比宽长 |
sensor |
由设备的物理方向传感器决定,如果用户旋转设备,这屏幕就会横竖屏切换 |
nosensor |
忽略物理方向传感器,这样就不会随着用户旋转设备而横竖屏切换了(”unspecified”设置除外) |
user |
用户当前首选的方向 |
reverseLandscape |
API 9 以上,反向横屏 |
reversePortrait |
API 9 以上,反向竖屏 |
sensorLandscape |
API 9 以上,横屏,但是可以根据 物理方向传感器来切换正反向横屏 |
sensorPortrait |
API 9 以上,竖屏,但是可以根据 物理方向传感器来切换正反向竖屏 |
fullSensor |
API 9 以上,上下左右四个方向,由物理方向传感器决定 |
locked |
API 18 以上,锁死当前屏幕的方向 |
上述代码中的android:configChanges所有可能的参数配置如下:
值 |
描述 |
---|---|
mcc |
IMSI移动台的国家代码(MCC)发生变化——一个SIM被探测到并且更新MCC |
mnc |
IMSI移动台的网络代码(MNC)发生变化——一个SIM被探测到并且更新MNC |
locale |
区域发生变化——用户选择了一个文本需要显示的新语言 |
keyboard |
键盘类型发生变化——例如:用户插入了外接键盘。 |
keyboardHidden |
键盘的可访问性发生变化——例如:用户发现了硬件键盘。 |
screenLayout |
屏幕布局发生变化——这个会导致显示不同的Activity。 |
orientation |
屏幕方向发生变化——用户旋转了屏幕。注意:如果应用程序的目标API级别是13或更高(通过属性minSdkVersion和属性targetSdkVersion声明),你也需要声明配置项screenSize,因为这将在设备选择肖像和屏幕方向时发生改变。 |
screenSize |
当前可用屏幕大小发生变化。这代表一个当前可用大小的变化,和当前的比率相关,因此当用户选择不同的画面和图像,会发生变化。然而,如果你的程序目标API级别是12或更低,你的Activity总是会自己处理这个配置变化(这个变化不会引起Activity的重启,甚至在Android 3.2或更新的设备上)。在API级别13里加入的。 |
smallestScreenSize |
物理屏幕大小的变化。不管方向的变化,仅仅在实际物理屏幕打包变化的时候,如:外接显示器。这个配置项的变化引起在smallestWidth configuration里的变化。然而,如果你的程序目标API级别是12或更低,你的Activity将自己处理这个变化(这个变化不会引起Activity的重启,甚至在Android 3.2或更新的设备上)在API级别13里加入的。 |
layoutDirection |
布局方向变化。例如书写方式从左向右(LTR)转换为从右向左(RTL) |
配置了以上属性之后,进行横竖屏切换的Activity的数据不会丢失,如果想根据不同的屏幕方向来展示不同UI或做不同的事,需要在该Activity中重写以下方法:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// 在这里添加屏幕切换后的操作
}
番外
我按照上述方法,根据重力传感器实现了屏幕旋转,虽然可以做到屏幕随重力传感器切换,但是发现:无论手机设置中“屏幕旋转”或“方向锁定”是开是关,App内的Activity都会随着手机的横竖方向切换横竖屏。我想要实现的是当打开“屏幕旋转”时,App内的Activity跟随重力感应器;当关闭“屏幕旋转”时,App内的Activity固定为默认方向。如何做到关闭重力传感器时,App亦关闭屏幕自动旋转?
android:screenOrientation="sensor"
改上述代码为以下代码
android:screenOrientation="user"
意即:当参数为sensor时,无论是否关闭“屏幕旋转”设置,App内的特定Activity都会根据重力传感器改变横竖屏。 当参数为user时,当“屏幕旋转”开启,则特定Activity根据根据重力传感器改变横竖屏;当“屏幕旋转”关闭,则特定Activity会固定位默认方向(一般为正面竖屏)。
以上就是本文的全部内容,希望对大家的学习有所帮助。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- JQuery的学习
- 网站图标开发指南
- 过滤器 & 监听器的学习
- 会话技术 & JSP 的学习
- 2万字,实战 Docker 部署:完整的前后端,主从热备高可用服务!!
- http & request & response的学习
- JavaScript 错误处理大全【建议收藏】
- Java8 用 Stream 快速实现List转Map 、分组、过滤等操作
- swoole框架异常处理
- 使用composer本地开发项目
- GDAL数据集写入空间坐标参考
- html & CSS & JavaScript的学习
- 打卡群刷题总结0824——电话号码的字母组合
- 打卡群刷题总结0825——括号生成
- Ajax与Json的学习