Android 屏幕的旋转 onConfigurationChanged方法

转载 2015年11月18日 14:43:12

Android 解决setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法

  最近在做播放器的时候遇到一个问题,在屏幕方向改变之后需要切换播放器全屏/非全屏的时候,在重写了onConfigurationChanged方法并在manifest.xml配置文件中添加

  1. android:screenOrientation="sensor"
  2. android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"

之后,在屏幕方向改变之后确实切换了播放器的方向,但是在我的程序中,需要一个播放器控制按钮,当用户点击按钮时手动切换播放器方向(即播放器全屏/小屏状态切换)和屏幕方向改变时自动切换两个功能并存;最开始想的是直接使用setRequestedOrientation()设置屏幕方向应该就OK了,但是发现这样做是行不通的.之后了解到因为setRequestedOrientation设置屏幕方向之后,比如说setRequestedOrientation(portrait)方法,就设定了屏幕方向是portrait,和在清单文件中配置android:screenOrientation="portrait"是同等的效果;也即不再响应屏幕方向改变,只支持portrait方向;

  言归正转,说我的处理方法,android给我们提供了OrientationEventListener,从字面意思就知道是干什么用的;这个监听器有一个onOrientationChanged(int rotation)方法会将当前屏幕旋转的度数返回给用户;

  先看持接口中方法返回的旋转度数的计算方法;

  

  上图中金色区域就是手机,角度就是绿线和红线之间的角度,顺时针旋转手机,角度增大,角度范围0-360;手机平放的角度为-1;

  下面分别是横屏和竖屏的界面,按钮即用于切换屏幕方向;

 

  再看看具体实现:

1.声明变量

    private OrientationEventListener mOrientationListener; // 屏幕方向改变监听器
    private boolean mIsLand = false; // 是否是横屏
    private boolean mClick = false; // 是否点击
    private boolean mClickLand = true; // 点击进入横屏
    private boolean mClickPort = true; // 点击进入竖屏

 

2.初始化监听器

复制代码
    /**
     * 开启监听器
     */
    private final void startListener() {
        mOrientationListener = new OrientationEventListener(this) {
            @Override
            public void onOrientationChanged(int rotation) {
                // 设置竖屏
                if (((rotation >= 0) && (rotation <= 30)) || (rotation >= 330)) {
                    if (mClick) {
                        if (mIsLand && !mClickLand) {
                            return;
                        } else {
                            mClickPort = true;
                            mClick = false;
                            mIsLand = false;
                        }
                    } else {
                        if (mIsLand) {
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                            mIsLand = false;
                            mClick = false;
                        }
                    }
                }
                // 设置横屏
                else if (((rotation >= 230) && (rotation <= 310))) {
                    if (mClick) {
                        if (!mIsLand && !mClickPort) {
                            return;
                        } else {
                            mClickLand = true;
                            mClick = false;
                            mIsLand = true;
                        }
                    } else {
                        if (!mIsLand) {
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                            mIsLand = true;
                            mClick = false;
                        }
                    }
                }
            }
        };
        mOrientationListener.enable();
    }
复制代码

3.设置按钮点击切换屏幕方向响应事件

复制代码
        mButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mClick = true;
                if (!mIsLand) {
                    if (onClickOrientationListener != null) {
                        onClickOrientationListener.landscape();
                    }
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    mIsLand = true;
                    mClickLand = false;
                } else {
                    if (onClickOrientationListener != null) {
                        onClickOrientationListener.portrait();
                    }
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    mIsLand = false;
                    mClickPort = false;
                }
            }
        });
复制代码

4.上面用到一个接口OnClickOrientationListener,里面包含两个方法,分别用于用户点击切换横屏/竖屏时的回调;

interface OnClickOrientationListener {
  public void landscape();
  public void portrait();
}

  代码贴完了, 简单说说思路,点击的时候,直接切换屏幕方向,切换之后,需要当手机屏幕也旋转到所切换的方向之后,才又开始监听手机屏幕旋转事件,这样就实现了setRequestedOrientation之后仍然可以通过旋转手机切换屏幕的功能;

  举个例子:
-->手机当前是竖屏状态,Activity也是竖屏状态 
-->用户点击切换按钮 
-->Activity切换为横屏,手机为竖屏;此时通过设置flag,使OrientationListener监听到竖屏时不再处理事件,waiting... 
-->直到当用户把手机旋转为横屏状态之后,更改flag,使OrientationListener监听到竖屏时处理相应的事件 
-->当用户再次旋转手机切换为竖屏之后,Activity即可自动切换为竖屏;

横屏点击切换竖屏理论同上;

  第三步,用户点击切换按钮之后进入横屏,此时就不响应监听到的竖屏处理事件,并且要等待到第四步用户把手机旋转为横屏状态之后再响应竖屏监听;这样定义似乎不太合理,但从用户的角度看,不可能用户点击了要进入横屏,却仍然把手机给竖屏方向拿着;

  最后,当不需要监听屏幕方向的时候,需要调用OrientationListener.disable()关闭监听器;

 

小记录一下相关知识01/07/2014

复制代码
    private int getScreenRotation() {
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        try {
            Method m = display.getClass().getDeclaredMethod("getRotation");
            return (Integer) m.invoke(display);
        } catch (Exception e) {
            return Surface.ROTATION_0;
        }
    }

    private int getScreenOrientation() {
        switch (getScreenRotation()) {
        case Surface.ROTATION_0:
            return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        case Surface.ROTATION_90:
            return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        case Surface.ROTATION_180:
            return (Build.VERSION.SDK_INT >= 8 ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
                    : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        case Surface.ROTATION_270:
            return (Build.VERSION.SDK_INT >= 8 ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                    : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        default:
            return 0;
        }
    }
复制代码

 

相关文章推荐

Android 监听屏幕旋转 onConfigurationChanged

注意:onConfigurationChanged事件并不是只有屏幕方向改变才可以触发,其他的一些系统设置改变也可以触发,比如打开或者隐藏键盘。 当我们的屏幕方向发生改变时,就可以触发onConfi...

Android 强制横屏或竖屏注意事项及onConfigurationChanged的使用

接上篇,尽管这个对旋转没有啥用但不代表么用。一个Activity如果在onReusume里没有特别声明,或没在AndroidManifest.xml配置成横屏或竖屏,在旋转时其声明周期为:onCrea...

Android中横竖屏切换时,onConfigurationChanged方法不被调用

在配置文件里,如果设置android:targetSdkVersion=”18”,那么必须android:configChanges=”orientation|keyboardHidden|scree...

Android 屏幕切换和onConfigurationChanged不调用的原因

Activity的生命周期大家都知道,通常我们会指定activity的屏幕方向,这样避免屏幕旋转改变后activity生命周期变化       android:screenOrientation="...

关于onConfigurationChanged以及onConfigurationChanged 未被调用的问题

通过查阅Android API可以得知android:onConfigurationChanged实际对应的是Activity里的onConfigurationChanged()方法。在Android...

Android屏幕转换及onConfigurationChanged事件解析

onConfigurationChanged事件是在改变屏幕方向、弹出软件盘和隐藏软键盘时,不再去执行onCreate()方法,而是直接执行onConfigurationChanged()。有的时候,...

Android 强制横屏或竖屏注意事项及onConfigurationChanged的使用

尽管这个对旋转没有啥用但不代表没用。一个Activity如果在onReusume里没有特别声明,或没在AndroidManifest.xml配置成横屏或竖屏,在旋转时其声明周期为:onCreate--...

Android重写onConfigurationChanged规避横竖屏切换时候重新进入onCreate生命周期

转载请注明出处:http://blog.csdn.net/zhangphil  Android重写onConfigurationChanged规避横竖屏切换时候重新进入onCreate...

Android之屏幕方向改变以及onConfigurationChanged事件

注意:onConfigurationChanged事件并不是只有屏幕方向改变才可以触发,其他的一些系统设置改变也可以触发,比如打开或者隐藏键盘。 当我们的屏幕方向发生改变时,就可以触发onConfi...

onConfigurationChanged会重新 OnCreate 的解决方案,onConfigurationChanged不被调用

在以前的版本中只要在AndroidManifest.xml文件中对activity指定android:configChanges="keyboardHidden|orientation"属性,转屏的时...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)