平常我们遇到的横竖屏切换最大的问题就是,屏幕切换后,原来界面中的东西会被清空,也就是Activity被重新创建。那么这时候就需要你做一些设置了,最简单的就是在AndroidMainfest.xml中设置activity中的android:screenOrientation属性值来实现。

 

(一)简单了解横竖屏的属性

既然通过属性进行控制横竖屏,那么我们就先来讲讲有哪些属性,分别代表什么意思。(其实也是为了自己以后方便查阅)

"unspecified":默认值 由系统来判断显示方向。这个和设备有关,不同设备会有不同的显示方向。

"landscape":横屏显示。

"portrait":竖屏显示。

"user":用户当前首选的方向。

"behind":和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)。

"sensor":由物理的感应器来决定。如果用户旋转设备,这时屏幕会横竖屏切换。

"nosensor":忽略物理感应器,这样就不会随者用户旋转设备而横竖屏切换了。

 

比如进行了以下设置:

android:screenOrientation="portrait"

则无论手机如何旋转,拥有这个属性的activity都始终竖屏显示。

android:screenOrientation="landscape"

则无论手机如何旋转,拥有这个属性的activity都始终横屏显示。

 

当然你也可以在代码中进行横竖屏的设置:

设置为竖屏

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

设置为横屏 

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

 

(二)如何阻止Activity被重建

下面就是我们最关心的,如何防止屏幕横竖屏切换而导致的Activty被重建。即当前界面中的数据不会因为屏幕的切换而消失。其实Android已经为我们提供了解决方案,就是通过onConfigrationChanged拦截横竖屏变换,从而进行必要的重新布局和切换操作。

首选,在AndroidManifest.xml文件中为相应的Activity设置android:configChanges属性,从而让Activity避免重建流程。

Android3.2以前的SDK可以使用如下配置:

android:configChanges="orientation|keyboardHidden"

Android3.2以后的SDK必须在原来基础上添加screenSize属性: 

android:configChanges="orientation|keyboardHidden|screenSize"

 

onConfigurationChanged()方法

在Activity中可以重写这个方法,当屏幕方向发生改变时的回调方法

/**
     * 系统配置发生改变时回调的方法
     * 包括系统语言、横竖屏切换、字体大小、键盘等
     * */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d(TAG, "onConfigurationChanged: "+newConfig.orientation);
    }

当然这个方法被调用的前提是,已经在AndroidManifest.xml文件中设置了configChanges属性“orientation”。需要注意的是,onConfigurationChanged函数中只能获得横竖屏切换后的参数。顺便说以下,这个方法其实在很多时候都会被回调,比如:切换系统语言、切换字体大小、接入键盘等。

 

(三)效果展示

android dialogfragment 横竖屏旋转 android横竖屏切换保存数据_Android

 

android dialogfragment 横竖屏旋转 android横竖屏切换保存数据_Android_02

 

(四)对于setRequestedOrientation函数的用法说明

      手动调用setRequestedOrientation之后,假如会引发横竖屏切换(即请求得横竖屏要求与当前得横竖屏状态不一致),那么会立即调用onConfigurationchanged函数;假如不会引发横竖屏切换(请求前后一致),那么就不会调用onConfigurationchanged函数。

       onConfigurationchanged函数得调用可以在Activity得任何地方,即也可以在它自身中调用,但是一旦通过这种设置完成横竖屏切换之后,那么后面不论屏幕如何翻转变化,都不会再触发横竖屏切换了,也就是等同于再AndroidManifest.xml中设置了android:screenOrientation属性为横屏或者竖屏。如要回复,则必须重新调用setRequestedOrientation方法。

 

(五)现场保护Fragment 

1.保持Fragment对象

主要用到了两个方法:


getSupportFragmentManager().findFragmentByTag()


setRetainInstance(true)


Fragment类:

@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: "+savedInstanceState);
        //保存fragment必须要加这条语句
        setRetainInstance(true);
    }

Activity类:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FragmentManager fm=getSupportFragmentManager();

        scoreFragment=fm.findFragmentByTag("scoreFragment");

        //如果fragment为空,则创建一个fragment
        if (scoreFragment==null){
            scoreFragment=new ScoreFragment();
            fm.beginTransaction().replace(android.R.id.content,scoreFragment,"scoreFragment")
                    .commit();
        }

        Log.d(TAG, "onCreate: ");
    }

 

 

2.保存和恢复Fragment的状态

调用回调函数onSaveInstanceState()将要保存的数据存入bundle中,然后在onCreate中进行提取数据,Activity类中的操作不变

@Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(SCORE,score);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: "+savedInstanceState);
        //保存fragment必须要加这条语句
        //setRetainInstance(true);

        //如果savedInstanceState不为空,则将保存的值取出来
        if (savedInstanceState!=null){
            this.score=savedInstanceState.getInt(SCORE);
        }
    }