博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 解决setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法...
阅读量:6717 次
发布时间:2019-06-25

本文共 5539 字,大约阅读时间需要 18 分钟。

  最近在做播放器的时候遇到一个问题,在屏幕方向改变之后需要切换播放器全屏/非全屏的时候,在重写了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;        }    }

 

转载于:https://www.cnblogs.com/a284628487/p/3361555.html

你可能感兴趣的文章
配置DNS 服务
查看>>
金笛电子邮件系统推出与RTX统一登陆整合方案
查看>>
Metronic 定制主题
查看>>
nginx限制连接数ngx_http_limit_conn_module模块
查看>>
Linux系统管理与维护之-cpio命令
查看>>
kvm虚拟化学习笔记(一)之kvm虚拟化环境安装
查看>>
rlwrap 小工具
查看>>
日志回传统计
查看>>
Cday01
查看>>
在CentOS上安装svn服务器
查看>>
可爱的python测试开发库(python测试开发工具库汇总)
查看>>
python返回汉字的首字母
查看>>
linux下yum更新出现HTTP Error 404 NOT FOUND错误的办法
查看>>
Nginx负载均衡配置实例
查看>>
Percona-mysql-5.5.38双主复制&mmm配置
查看>>
spring高级 之 拦截器
查看>>
安卓的生命周期和布局大概
查看>>
使用APC加速你的PHP网站
查看>>
Redis Windows 服务启动异常 错误码1067
查看>>
关于 pip安装的可能错误的排除
查看>>