Android编程之横屏竖屏切换及状态保留

Android编程之横屏竖屏切换及状态保存

总体来说有两种方案:

1.Android系统自动切换

  利用Android系统每次屏幕切换会重启Activity的特性,在OnCreat处自动加载不同显示状态下的layout。

  例:main.xml是竖屏状态下的layout,文件保存于res/layout文件夹中。为实现横屏切换,建立文件夹res/layout-land,在里面创建新的界面文件main.xml,与res/layout文件夹中文件同名。则当设备由竖屏切换到横屏,或者反之时,在onCreate()函数中直接执行setContentView(R.layout.main)即可自动加载不同的界面文件。

  另外,在res/layout-land中建立同名文件是用系统自动判断加载,也可以手动判断加载。如在res/layout文件夹中有竖屏界面main-P.xml及横屏界面main-L.xml,则可以在onCreate()函数中通过判断横竖屏状态以显式加载不同界面,代码:

int mCurrentOrientation = getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ) {

   // If current screen is portrait

   setContentView(R.layout.main-P);

} else if ( mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE ) {

   //If current screen is landscape

   setContentView(R.layout.main-L);

}

  由于android系统屏幕切换会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置。

2.利用Activity的onConfigurationChanged()方法手动切换

  为避免Android系统自动重启activity,需要在Androidmanifest.xml中相应Activity加上android:configChanges="keyboardHidden|orientation"属性,使相应的Activity不重启而是调用onConfigurationChanged(Configuration newConfig)。

  例:res/layout下有竖屏界面main-P.xml及横屏界面main-L.xml。onCreate()时同理判断以显示不同的界面:

    @Override

    protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

int mCurrentOrientation = getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ) {

     // If current screen is portrait

     setContentView(R.layout.main-P);

} else if ( mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE ) {

     //If current screen is landscape

     setContentView(R.layout.main-L);

}



init();//初始化,赋值等操作

findViews();//获得控件

setListensers();//设置控件的各种监听方法

    }

  重载onConfigurationChanged():

    @Override

    public void onConfigurationChanged (Configuration newConfig){

super.onConfigurationChanged(newConfig);




int mCurrentOrientation = getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ) {

   // If current screen is portrait

   setContentView(R.layout.main-P);

   //注意,这里删除了init(),否则又初始化了,状态就丢失

   findViews();

   setListensers();

} else if ( mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE ) {

   //If current screen is landscape

   setContentView(R.layout.main-L);

   //注意,这里删除了init(),否则又初始化了,状态就丢失

   findViews();

   setListensers();

}

    }

  以上代码中需要注意init()函数,若需要保存其它的状态,如Button及各种View的显示文字已经改变,在setListensers()务必进行恢复操作。

  同样,也可以使用res/layout/main.xml和res/layout-land/main.xml方式,则不需判断,直接使用setContentView(R.layout.main)即可。看代码:

    @Override

    protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);



init();//初始化,赋值等操作

findViews();//获得控件

setListensers();//设置控件的各种监听方法

    }

  重载onConfigurationChanged():

    @Override

    public void onConfigurationChanged (Configuration newConfig){

super.onConfigurationChanged(newConfig);




int mCurrentOrientation = getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ) {

   // If current screen is portrait

   setContentView(R.layout.main);

   //注意,这里删除了init(),否则又初始化了,状态就丢失

   findViews();

   setListensers();

} else if ( mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE ) {

   //If current screen is landscape

   setContentView(R.layout.main);

   //注意,这里删除了init(),否则又初始化了,状态就丢失

   findViews();

   setListensers();

}

    }

  其实在这种模式下,由于Android系统自动寻找不同界面文件,而Androidmanifest.xml中已定义了android:configChanges="keyboardHidden|orientation"只监听方向改变,因此onConfigurationChanged()方法还可以继续精简(除非在横竖屏下状态不同),直接设置界面、恢复状态即可:

    @Override

    public void onConfigurationChanged (Configuration newConfig){

super.onConfigurationChanged(newConfig);




setContentView(R.layout.main);

//注意,这里删除了init(),否则又初始化了,状态就丢失

findViews();

setListensers();

    }