Activity在屏幕显示的方向切换

时间:2022-06-27 16:20:39

 

Activity在屏幕显示的方向切换

 

  android:screenOrientationandroid:configChanges

 

  Activity的内容在屏幕上的显示方向,有时会旋转。

  activity内容方向的设定与转换,以及相关的生命周期处理,是与Manifest中activity标签下的下面两个属性相关的:

  即android:screenOrientationandroid:configChanges

  (链接中有所有属性的说明:http://developer.android.com/guide/topics/manifest/activity-element.html#screen

 

Android的屏幕方向状态是下列的值之一:

 

ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE

ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

ActivityInfo.SCREEN_ORIENTATION_USER

ActivityInfo.SCREEN_ORIENTATION_BEHIND

ActivityInfo.SCREEN_ORIENTATION_SENSOR

ActivityInfo.SCREEN_ORIENTATION_NOSENSOR

ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE

ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT

ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE

ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT

ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR

 

 

方向属性设置

  我们可以利用android:screenOrientation属性强制锁定屏幕的方向。

  也可以把方向设定为随着传感器而变化。

  下面是这个属性可以设定的值。

 Activity在屏幕显示的方向切换

                        

  在程序中也可以调用setRequestedOrientation方法进行屏幕方向的动态设置,具体请参见文后参考资料的第二个链接。

 

方向转换与生命周期

  当在manifest中把android:screenOrientation的属性设为sensor时:

 

        <activity
            android:name=".HelloOrientationActivity"
            android:label="@string/title_activity_hello_orientation"
            android:screenOrientation="sensor" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

  运行程序可以发现Activity的显示内容的确会随着手机的姿态进行横竖屏的切换。

  但是观察生命周期的相关函数调用Log,发现在进行横竖屏切换的时候整个activity会调用onPause()、onStop()、onDestroy()然后重新调用onCreate()、onResume()。

  并且此时覆写onConfigurationChanged()是不会被调用的。 

 

  查看android:configChanges部分的文档可以发现,默认情况下activity是会关闭并且重启的,但是通过这个属性可以阻止activity的重启行为,让activity保持运行,并且activity的onConfigurationChanged()将会被调用。

  (默认情况下这个方法是不会被调用的)。

  但是官方不建议用这个属性来处理,建议看看 Handling Runtime Changes 。

  这个属性设置的各种值就是要阻止activity重启的各种情况。

  比如设置为:

        <activity
            android:name=".HelloOrientationActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/title_activity_hello_orientation"
            android:screenOrientation="sensor" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

  这样在屏幕旋转并切换横竖屏的时候,发现activity并没有被重建,而是调用了onConfigurationChanged()方法。

 

补充一下:

  当android:targetSdkVersion大于等于13时, 要想onConfigurationChanged()方法被调用,mainfest中需要这样写:

<activity
            android:name="com.example.helloorientation.MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:screenOrientation="sensor" >
......

 

测试程序

  附上测试程序代码:

Activity在屏幕显示的方向切换Activity在屏幕显示的方向切换
package com.example.helloactivityorientation;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class HelloOrientationActivity extends Activity
{

    private static final String LOG_TAG = "Hello Orientation";

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.i(LOG_TAG, "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hello_orientation);

    }

    @Override
    protected void onResume()
    {
        Log.i(LOG_TAG, "onResume");
        super.onResume();
    }

    @Override
    protected void onPause()
    {
        Log.i(LOG_TAG, "onPause");
        super.onPause();
    }

    @Override
    protected void onStop()
    {
        Log.i(LOG_TAG, "onStop");
        super.onStop();
    }

    @Override
    protected void onDestroy()
    {
        Log.i(LOG_TAG, "onDestroy");
        super.onDestroy();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        Log.i(LOG_TAG, "onConfigurationChanged");
        super.onConfigurationChanged(newConfig);
    }

}
Activity代码

 

Activity在屏幕显示的方向切换Activity在屏幕显示的方向切换
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloactivityorientation"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".HelloOrientationActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/title_activity_hello_orientation"
            android:screenOrientation="sensor" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Manifest代码


  布局代码略,能看出正反向就行,TextView里写个HelloWorld就可以了。

 

 

参考资料

  官方文档中activity标签下的元素说明:

  http://developer.android.com/guide/topics/manifest/activity-element.html

  一个英文的关于屏幕方向的文章:

  http://techblogon.com/android-screen-orientation-change-rotation-example/