Realization of Horizontal Screen and Vertical Screen Switching in Android Screen Rotation

  • 2021-11-13 18:01:05
  • OfStack

Just realized the horizontal/vertical screen switching when the mobile phone is placed horizontally/vertically in App. Record the key information and implementation process needed in the middle of 1.

To cut to the chase, there are two ways to realize automatic/manual screen rotation:

One is defined in the code of the project. The operation performed in this way when switching between horizontal and vertical screens is to destroy the current Activity and rebuild Activity according to the new screen size. If the data storage operation is not performed, the data in Activity will be lost during the handover.

The other is defined in AndroidManifest. xml of the project. In some cases, this definition method can realize "Activity requiring horizontal and vertical screens", because this method will not destroy Activity and rebuild Activity, so the data of Activity will not be lost.

Next, we introduce these two implementations respectively:

Mode 1: Define in the code

Add the following statement to the onCreate method in the Activity that requires a horizontal screen, and require it to precede the setContentView (**) statement in the onCreate method.


setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

In the previous statement, the constant SCREEN_ORIENTATION_FULL_SENSOR is the parameter that determines how the screen rotates. Summarize the functions corresponding to all parameters:

参数 功能
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 另1个方向的横屏
SCREEN_ORIENTATION_REVERSE_PORTRAIT 另1个方向的竖屏(倒拿手机)
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 当屏幕较窄时导航栏有1部分会显示在底部

Since the data of the corresponding Activity will be lost when the horizontal/vertical screen is switched in this mode, the following two methods can be rewritten in the corresponding Activity to ensure that the data is not lost:


@Override
protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  // Called before switching between horizontal and vertical screens to save the data that users want to save. The following is an example 
  outState.putString("name","yoosir"); 
  outState.putInt("age",24); 
  outState.putBoolean("handsome",true);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  //  After screen switching, call the data stored by the user. Here is an example: 
  if(savedInstanceState != null) { 
    int age = savedInstanceState.getInt("age"); 
    String name = savedInstanceState.getString("name"); 
    boolean isHandsome = savedInstanceState.getBoolean("handsome");
  }
}

Mode 2: Defined in AndroidManifest. xml

Configure android: configChanges and screenOrientation in the corresponding Activity attribute definition in AndroidManifest. xml. In the reference article, the configuration of android: configChanges is very clear, so I will post the conclusion directly:


android:configChanges="orientation|keyboardHidden|screenSize"
When you configure configChanges to the above configuration, Screen Cutting does not recall the lifecycle, but only executes the onConfigurationChanged method. Data in Activity is not destroyed. When configChanges is not configured or configChanges is not configured above, the screen will recall each life cycle of the current Activity. The data in Activity is destroyed.

The example code is as follows:


<activity android:name=".com.cdsn.SearchActivity"
  ... ...
  android:screenOrientation="sensor"
  android:configChanges="keyboardHidden|orientation|screenSize"
      />

All possible parameter configurations for android: screenOrientation in the above code are as follows.

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

All possible parameter configurations for android: configChanges in the above code are as follows:

描述
mcc IMSI移动台的国家代码(MCC)发生变化――1个SIM被探测到并且更新MCC
mnc IMSI移动台的网络代码(MNC)发生变化――1个SIM被探测到并且更新MNC
locale 区域发生变化――用户选择了1个文本需要显示的新语言
keyboard 键盘类型发生变化――例如:用户插入了外接键盘。
keyboardHidden 键盘的可访问性发生变化――例如:用户发现了硬件键盘。
screenLayout 屏幕布局发生变化――这个会导致显示不同的Activity。
orientation 屏幕方向发生变化――用户旋转了屏幕。注意:如果应用程序的目标API级别是13或更高(通过属性minSdkVersion和属性targetSdkVersion声明),你也需要声明配置项screenSize,因为这将在设备选择肖像和屏幕方向时发生改变。
screenSize 当前可用屏幕大小发生变化。这代表1个当前可用大小的变化,和当前的比率相关,因此当用户选择不同的画面和图像,会发生变化。然而,如果你的程序目标API级别是12或更低,你的Activity总是会自己处理这个配置变化(这个变化不会引起Activity的重启,甚至在Android 3.2或更新的设备上)。在API级别13里加入的。
smallestScreenSize 物理屏幕大小的变化。不管方向的变化,仅仅在实际物理屏幕打包变化的时候,如:外接显示器。这个配置项的变化引起在smallestWidth configuration里的变化。然而,如果你的程序目标API级别是12或更低,你的Activity将自己处理这个变化(这个变化不会引起Activity的重启,甚至在Android 3.2或更新的设备上)在API级别13里加入的。
layoutDirection 布局方向变化。例如书写方式从左向右(LTR)转换为从右向左(RTL)

After the above attributes are configured, the data of Activity for horizontal and vertical screen switching will not be lost. If you want to display different UI or do different things according to different screen directions, you need to rewrite the following methods in this Activity:


@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  //  Add the action after screen switching here 
}

Fanwai

According to the above method, I realized the screen rotation according to the gravity sensor. Although the screen can be switched with the gravity sensor, I found that Activity in App will switch the horizontal and vertical screens with the horizontal and vertical directions of the mobile phone regardless of whether the "screen rotation" or "direction locking" in the mobile phone setting is on or off. What I want to achieve is that when "screen rotation" is turned on, Activity in App follows the gravity sensor; When Screen Rotation is turned off, Activity within App is fixed to the default direction. How to turn off the gravity sensor when App also turns off the automatic rotation of the screen?


android:screenOrientation="sensor"

Change the above code to the following code


android:screenOrientation="user"

This means that when the parameter is sensor, the specific Activity in App will change the horizontal and vertical screens according to the gravity sensor, whether or not the "screen rotation" setting is turned off.
When the parameter is user, when "screen rotation" is turned on, the specific Activity changes the horizontal and vertical screens according to the gravity sensor; When "screen rotation" is turned off, the specific Activity will fix the default direction (1 is generally a front vertical screen).


Related articles: