3.动态方向锁定

3.1 问题

在某些特定的条件下,不能让屏幕旋转,但这个条件是临时的或是根据用户的意愿决定的。

3.2 解决方案

(API Level 1)
借助Android的请求方向机制(requested orientation mechanism),应用程序可以调整显示Activity的屏幕方向,将其固定为某个方向或是交由设备决定。这是通过调用Activity.SetReActivity的屏幕方向。这通常是根据设备的物理方向来确定的。当前请求的方向可以随时通过调用Activity.getRequestedOrientation()方法获得。

3.3 实现机制

举个示例,让我们创建一个ToggleButton实例来控制是否锁定当前屏幕方向,这样就能让用户随时控制Activity的方向。以下代码描绘了在其中定义ToggleButton实例的简单布局。
res/layout/activity_lock.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ToggleButton
        android:id="@+id/toggleButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textOff="Lock"
        android:textOn="LOCKED" />
</FrameLayout>

在Activity代码中,我们给这个按钮的状态创建一个监听器,根据按钮的值决定锁定或解锁屏幕的方向(参见以下代码)。
动态锁定/解锁屏幕方向的Activity

public class LockActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lock);

        //获得按钮资源的句柄
        ToggleButton toggle = (ToggleButton)findViewById(R.id.toggleButton);
        //在添加监听器之前设置默认状态
        if( getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED ) {
            toggle.setChecked(true);
        } else {
            toggle.setChecked(false);
        }
        //将监听器关联到按钮
        toggle.setOnCheckedChangeListener(new OrientationLockListener());
    }

    private class OrientationLockListener implements CompoundButton.OnCheckedChangeListener {

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            int current = getResources().getConfiguration().orientation;
            if(isChecked) {
                switch(current) {
                case Configuration.ORIENTATION_LANDSCAPE:
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    break;
                case Configuration.ORIENTATION_PORTRAIT:
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    break;
                default:
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                }
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
            }
        }
    };
}

监听器中的这段代码是本攻略的关键。如果用户按下这个按钮,将其置为ON状态,应用程序就通过保存Resources.getConfiguration()的orientation参数读取当前的屏幕方向。Configuration对象 用来表示屏幕方向的常数与所请求的方向使用的常数不同,所以我们根据当前的屏幕方向进行切换,然后再用合适的常熟调用setRequestedOrientation()方法。

注意:
如果所请求的方向跟当前状态不一样,且Activity在前台,Activity就会立即切换方向以满足请求。

如果用户按下了这个按钮,将其设为OFF状态,我们就不再锁定方向,因此用SCREEN_ORIENTATION_UNSPECIFIED常数再调用一次setRequestedOrientation(),将控制权交还给设备。如果设备当前的物理方向跟移除锁定时的Activity方向不一致,也会导致屏幕切换方向。

注意:
设置请求的方向不会保持默认的Activity生命周期。如果设备配置发生变化(例如物理键盘弹出,或是设备方向改变),Activity依然会被销毁并重新创建,因此所有保持Activity状态的规则都适用。

猜你喜欢

转载自blog.csdn.net/qq_41121204/article/details/82861804
3.