Android screen rotation

Reprinted from: https://blog.csdn.net/qqwuy_muzi/article/details/68942118
By default, when the "screen rotation" option of the user's mobile phone is turned on and the mobile phone is rotated, the mobile phone screen will also follow the direction of rotation. screen switching.

There are two ways to set screen rotation:

1. Setting in AndroidManifest.xml

  If the activity is a certain mode by default, you can directly add the corresponding code in the corresponding activity item in AndroidManifest.xml to achieve

  Such as:

    android:screenOrientation=”unspecified” Follow the system screen rotation direction, etc. (default)

    android:screenOrientation=”landscape” force landscape

    android:screenOrientation=”portrait” Force vertical screen

2. Code dynamic settings

  If you need to dynamically set the display orientation of the activity on the screen, you can call the api function provided by the system: setRequestedOrientation(@ActivityInfo.ScreenOrientationint requestedOrientation).

  The main corresponding value of requestedOrientation:

   ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

   ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE

   ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

3. Detailed parameters of android:screenOrientation

Four. android:configChanges settings (self-handling configuration changes)

  When the rotation method we set follows the system, that is, android:screenOrientation=”unspecified”, then if the screen orientation changes, the Activity will be destroyed, and then the Activity will be recreated.

  (The restart behavior is designed to help your app adapt to the new configuration by automatically reloading it with alternate resources that match the new device configuration.)

  Rebooting and restoring large amounts of data is not only expensive, affects performance, but also leaves users with a poor experience.

  If you don't want Activity to be destroyed, you need to configure android:configChanges in AndroidManifest.xml

  E.g:

     
  Note: Starting with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape. Therefore, when developing for API level 13 or higher (as the minSdkVersion and targetSdkVersion properties ), to avoid runtime restarts due to device orientation changes, you must add the "screenSize" value in addition to the "orientation" value. That is, you must declare android:configChanges=" orientation|screenSize". However, if your app targets API level 12 or lower, the Activity always handles this configuration change itself (even if running on an Android 3.2 or higher device, this configuration change will not restart Activity).)

   After adding this code, if you rotate the phone screen again, the Activity will not be destroyed, but will call back the onConfigurationChanged method in the activity, then you need to deal with the relevant logic here.

5. Detailed parameters of android:configChanges

6. About the use of multiple sets of resources such as horizontal and vertical screens

  As shown above, we can configure multiple sets of resource files under Res at the same time, layout is the default resource file, and layout-land is the resource file under the horizontal screen. (value and other resources can also be configured with multiple sets)

  If the android:configChanges setting is not configured, and the configuration changes are not processed by itself, after the activity is destroyed and rebuilt, it will automatically load the resources in the corresponding directory. The developer only needs to prepare multiple sets of resources at the same time, and does not need to pay attention at runtime. Configuration changes (screen orientation rotation, etc.).

  If you configure the android:configChanges setting, it will handle configuration changes by itself, and the activity will load the resources under the corresponding resource file when it is created, that is, if it comes in horizontally, it will load the resource file under layout-land. Later When the configuration changes (screen orientation rotation, etc.), the activity will no longer load resources (even if multiple sets of resources are configured), then you need to refresh the corresponding resource files according to the Configuration parameter in the onConfigurationChanged method.

7. Get the current screen horizontal and vertical screen status

  You can get the status value of the current screen orientation through getResources().getConfiguration().orientation

  Configuration.ORIENTATION_LANDSCAPE means landscape

8. About the onConfigurationChanged method

 The onConfigurationChanged callback is not only in the activity, but also in the fragment and view, viewgroup, etc.

 The following is the callback flow of onConfigurationChanged:

 1.activity

  Receive the configuration change message in ActivityThread, then handle it in handleActivityConfigurationChanged and performConfigurationChanged, and call back to activity.

  If there are multiple activities, only the running activity will be called back, and other activities will only be called back when it is reactivated and the screen state is different from the current state (the official only said that the running activity is called back, but the test proves that after the click returns, other activities are called back. The activity will also call back)

final voidhandleActivityConfigurationChanged(ActivityConfigChangeData data) {

ActivityClientRecord r =mActivities.get(data.activityToken);

if (r == null || r.activity == null) {

return;

}

if (DEBUG_CONFIGURATION) Slog.v(TAG,”Handle activity config changed: “

  • r.activityInfo.name);

r.tmpConfig.setTo(mCompatConfiguration);

if (data.overrideConfig != null) {

r.overrideConfig =data.overrideConfig;

r.tmpConfig.updateFrom(data.overrideConfig);

}

performConfigurationChanged(r.activity,r.tmpConfig);

freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));

mSomeActivitiesChanged = true;

}

private static voidperformConfigurationChanged(ComponentCallbacks2 cb, Configurationconfig) {

// Only for Activity objects, check thatthey actually call up to their

// superclass implementation. ComponentCallbacks2 is an interface, so

// we check the runtime type and actaccordingly.

Activity activity = (cb instanceofActivity) ? (Activity) cb : null;

if (activity != null) {

activity.mCalled = false;

}

boolean shouldChangeConfig = false;

if ((activity == null) ||(activity.mCurrentConfig == null)) {

shouldChangeConfig = true;

} else {

// If the new config is the same asthe config this Activity

// is already running with then don’tbother calling

// onConfigurationChanged

int diff =activity.mCurrentConfig.diff(config);

if (diff != 0) {

// If this activity doesn’t handleany of the config changes

// then don’t bother callingonConfigurationChanged as we’re

// going to destroy it.

if((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {

shouldChangeConfig = true;

}

}

}

if (DEBUG_CONFIGURATION) Slog.v(TAG,”Config callback ” + cb

  • “: shouldChangeConfig=”+ shouldChangeConfig);

if (shouldChangeConfig) {

cb.onConfigurationChanged(config);

if (activity != null) {

if (!activity.mCalled) {

throw newSuperNotCalledException(

“Activity “+ activity.getLocalClassName() +

” did not callthrough to super.onConfigurationChanged()”);

}

activity.mConfigChangeFlags = 0;

activity.mCurrentConfig = newConfiguration(config);

}

}

}

 2.fragment

  (1) Processing in Activity

public voidonConfigurationChanged(Configuration newConfig) {

if (DEBUG_LIFECYCLE) Slog.v(TAG,”onConfigurationChanged ” + this + “: ” +newConfig);

mCalled = true;

mFragments.dispatchConfigurationChanged(newConfig);

if (mWindow != null) {

// Pass the configuration changedevent to the window

mWindow.onConfigurationChanged(newConfig);

}

if (mActionBar != null) {

// Do this last; the action bar willneed to access

// view changes from above.

mActionBar.onConfigurationChanged(newConfig);

}

}

  (2) Forwarding in FragmentController

public voiddispatchConfigurationChanged(Configuration newConfig) {

mHost.mFragmentManager.dispatchConfigurationChanged(newConfig);

}

  (3) All fragments distributed to the activity in FragmentManager

public voiddispatchConfigurationChanged(Configuration newConfig) {

if (mAdded != null) {

for (int i=0; i

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324409225&siteId=291194637