Android 解决setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法
最近在做播放器的时候遇到一个问题,在屏幕方向改变之后需要切换播放器全屏/非全屏的时候,在重写了onConfigurationChanged方法并在manifest.xml配置文件中添加
- android:screenOrientation="sensor"
- 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 解决setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法的更多相关文章
- Android程序对不同手机屏幕分辨率自适应的方法
相信各位Android开发爱好者都知道,由于OEM之间的竞争,各种Android操作系统的手机简直就是琳琅满目,屏幕分辨率的差异可想而知.目前比较主流的有WVGA=800x480,HVGA=480x3 ...
- Android针对不同的手机屏幕大小设计图片资源与编码
注:本文转载于:http://blog.csdn.net/welovesunflower/article/details/7930248 一些术语 Screen Size 屏幕尺寸: 实际的物理尺寸, ...
- Android应用不随手机屏幕旋转的方法
在主配置文件里面.在需要设置的activity项后面加上 android:screenOrientation="portrait",这个activity就保持竖屏显示了:在每个ac ...
- Android中如何让手机屏幕不待机
在Android中,申请WakeLock可以让你的进程持续执行即使手机进入睡眠模式,比较实用的是比如后台有网络功能,可以保证操作持续进行. 方法: 在操作之前加入 PowerManager pm = ...
- android 解决 多品牌手机拍照问题,尤其是小米手机
先上个图吧 .点击头像弹出下面对话框,然后直接上代码. 头像是自定义控件实现的圆形头像,当然就目前而言 想要实现 圆形头像的资料太多了,随便找个就行 <com.kuibu.jucai.widge ...
- iOS学习之自定义视图时,在屏幕发生旋转时触发重新布局方法
如果要对自定义的视图在屏幕旋转时重新布局,则在自定义视图中定义以下触发方法: -(void)layoutSubviews { [super layoutSubviews]; //1.获取到屏幕旋转的方 ...
- Android手机屏幕投射到电脑神器Vysor
做android开发的,经常要把手机屏幕投射到电脑,用来演示.普遍的解决方案是360或者豌豆荚的演示功能,缺点是延迟非常厉害,大概有3秒左右,非常影响演示效果.以下介绍Vysor,几乎0延迟,能与手机 ...
- 【WP开发】在手机屏幕点亮时播放声音
今天说的内容有点流氓,请诸君在开发应用时谨慎使用. 那么,这活儿到底有多流氓呢? 先介绍一下要实现的功能:当用户按电源键(也可以是双击屏幕)点亮手机的屏幕时播放一下短音乐,而且应用程序可以不在前台运行 ...
- 解决Android手机 屏幕横竖屏切换
Android中当屏幕横竖屏切换时,Activity的生命周期是重新加载(说明当前的Activity给销毁了,但又重新执行加载),怎么使屏幕横竖屏切换时,当前的Activity不销毁呢? 1. 在An ...
随机推荐
- LeetCode 169. Majority Element - majority vote algorithm (Java)
1. 题目描述Description Link: https://leetcode.com/problems/majority-element/description/ Given an array ...
- sql月,年,统计报表sql报表
select DevName as 设备名称, count(flux) as 流量数据个数, max(flux) as 流量最大值, min(flux) as 流量最小值, avg(flux) as ...
- vue.js学习之 跨域请求代理与axios传参
vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{}, ...
- finecms
finecms地址 还不错的国内CMS http://www.dayrui.com/doc/246.html
- Java中I/O流之数据流
Java 中的数据流: 对于某问题:将一个 long 类型的数据写到文件中,有办法吗? 转字符串 → 通过 getbytes() 写进去,费劲,而且在此过程中 long 类型的数需要不断地转换. ...
- Swift中避免在多个文件中重复import相同的第三方包
swift中由于有命名空间的存在,在同一个target创建的文件,都可以不引用直接就可以拿来使用,但是不同target之间必须要import 之后才能使用,在不同的文件中使用都要重复的import这个 ...
- PagedDataSource数据绑定控件和AspNetPager分页控件结合使用列表分页
1.引用AspNetPager.dll. 2.放置Repeater数据绑定控件. <asp:Repeater ID="Repeater1" runat="serve ...
- PowerMock用法[转]
转:http://agiledon.github.io/blog/2013/11/21/play-trick-with-powermock/ 当我们面对一个遗留系统时,常见的问题是没有测试.正如Mic ...
- 【Mysql】- Mysql 8.0正式版新亮点
MySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8 ...
- react项目开发入门
v16.2.0 在html头部引入react相关js文件 <!-- react核心库--><script src="../static/react/react.produc ...