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的使用

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

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

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

android 4.0以上横竖屏切换不销毁activity,不重新走生命周期,只调用onConfigurationChanged

原文地址是:http://dzc.iteye.com/blog/2090512 网上很多文章都是说 在 AndroidManifest.xml 文件中的设置 Activity 元素的 ...

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

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

android如何改变系统默认横竖屏方向

http://blog.csdn.net/abc19842008/article/details/7543559 如何改变android默认的横竖屏,修改源码一个地方就可以了。 ...

Android屏幕旋转监听onConfigurationChanged

Android视频播放器实现小窗口和全屏状态切换

Android视频播放器实现小窗口和全屏状态切换实在是不好意思,楼下评论的兄弟久等了,这文章一直没写第一是没时间,第二是自己准备也不充足,最近才看了好几个Android视频播放器的开源项目,才对视频播...

Android屏幕转换及onConfigurationChanged事件解析

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

屏幕旋转--自动及手动控制(视频播放中setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法)

在调用了setRequestedOrientation之后,手机屏幕的旋转不触发onConfigurationChanged方法,这个时候需要再调用一次...

Android 监听屏幕旋转 onConfigurationChanged

注意:onConfigurationChanged事件并不是只有屏幕方向改变才可以触发,其他的一些系统设置改变也可以触发,比如打开或者隐藏键盘。 当我们的屏幕方向发生改变时,就可以触发onConfi...
  • zwq1457
  • zwq1457
  • 2012年09月12日 19:48
  • 19138
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 屏幕的旋转 onConfigurationChanged方法
举报原因:
原因补充:

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