最近在做播放器的时候遇到一个问题,在屏幕方向改变之后需要切换播放器全屏/非全屏的时候,在重写了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 解决setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法的更多相关文章

  1. Android程序对不同手机屏幕分辨率自适应的方法

    相信各位Android开发爱好者都知道,由于OEM之间的竞争,各种Android操作系统的手机简直就是琳琅满目,屏幕分辨率的差异可想而知.目前比较主流的有WVGA=800x480,HVGA=480x3 ...

  2. Android针对不同的手机屏幕大小设计图片资源与编码

    注:本文转载于:http://blog.csdn.net/welovesunflower/article/details/7930248 一些术语 Screen Size 屏幕尺寸: 实际的物理尺寸, ...

  3. Android应用不随手机屏幕旋转的方法

    在主配置文件里面.在需要设置的activity项后面加上 android:screenOrientation="portrait",这个activity就保持竖屏显示了:在每个ac ...

  4. Android中如何让手机屏幕不待机

    在Android中,申请WakeLock可以让你的进程持续执行即使手机进入睡眠模式,比较实用的是比如后台有网络功能,可以保证操作持续进行. 方法: 在操作之前加入 PowerManager pm = ...

  5. android 解决 多品牌手机拍照问题,尤其是小米手机

    先上个图吧 .点击头像弹出下面对话框,然后直接上代码. 头像是自定义控件实现的圆形头像,当然就目前而言 想要实现 圆形头像的资料太多了,随便找个就行 <com.kuibu.jucai.widge ...

  6. iOS学习之自定义视图时,在屏幕发生旋转时触发重新布局方法

    如果要对自定义的视图在屏幕旋转时重新布局,则在自定义视图中定义以下触发方法: -(void)layoutSubviews { [super layoutSubviews]; //1.获取到屏幕旋转的方 ...

  7. Android手机屏幕投射到电脑神器Vysor

    做android开发的,经常要把手机屏幕投射到电脑,用来演示.普遍的解决方案是360或者豌豆荚的演示功能,缺点是延迟非常厉害,大概有3秒左右,非常影响演示效果.以下介绍Vysor,几乎0延迟,能与手机 ...

  8. 【WP开发】在手机屏幕点亮时播放声音

    今天说的内容有点流氓,请诸君在开发应用时谨慎使用. 那么,这活儿到底有多流氓呢? 先介绍一下要实现的功能:当用户按电源键(也可以是双击屏幕)点亮手机的屏幕时播放一下短音乐,而且应用程序可以不在前台运行 ...

  9. 解决Android手机 屏幕横竖屏切换

    Android中当屏幕横竖屏切换时,Activity的生命周期是重新加载(说明当前的Activity给销毁了,但又重新执行加载),怎么使屏幕横竖屏切换时,当前的Activity不销毁呢? 1. 在An ...

随机推荐

  1. CakePHP 总结

    1. 处理任何保存或获取数据的操作最好都写在模型(Model)中.这个概念通常被称为fat model. 2. 返回上一条插入记录的ID, $this->Example->getInser ...

  2. JS学习 用 arguments 对象模拟函数重载

    用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载: function doAdd() { if(arguments.length == 1) { alert(arguments[ ...

  3. js函数相关高级用法

    一.惰性载入函数(lazy function) 使用场景:当一个函数中的判断分支只用执行一次(第一次调用时执行),后续不会再变化,则可以使用惰性函数来提高性能. var addEvent = func ...

  4. 开发发布npm module包

    开发发布npm module包 问题 在项目开发过程中,每当进入一个新的业务项目,从零开始搭建一套前端项目结构是一件让人头疼的事情,就要重新复制一个上一个项目的前端框架和组件代码库.其中很多功能的模块 ...

  5. MySQL日期、字符串、时间戳互转

    平时比较常用的时间.字符串.时间戳之间的互相转换,虽然常用但是几乎每次使用时候都喜欢去搜索一下用法:本文将作为一个笔记,整理一下三者之间的 转换(即:date转字符串.date转时间戳.字符串转dat ...

  6. Qt-QPalette-调色板学习

    已经很久没有更新博客了,一是因为换了公司,完全是断网开发了,没有时间来写博客,最主要的就是温水煮青蛙,自己在舒适的环境中越来越懒了,最近打算强制自己更新一波.不知道能坚持多久.由于目前没有具体的Qt项 ...

  7. 【isJson( jsonObj )】判断是否是JSON实例

    判断是否是JSON实例: 原型:isJson( jsonObj ) 说明:判断对象是否是JSON实例 返回:[true | false] 示例: <% Set jsonObj1 = toJson ...

  8. 论文笔记:Deep Attentive Tracking via Reciprocative Learning

    Deep Attentive Tracking via Reciprocative Learning NIPS18_tracking Type:Tracking-By-Detection 本篇论文地主 ...

  9. LeetCode 100——相同的树

    1. 题目 2. 解答 针对两棵树的根节点,有下列四种情况: p 和 q 都为空,两棵树相同: p 不为空 q 为空,两棵树不相同: p 为空 q 不为空,两棵树不相同: p 和 q 都不为空,如果两 ...

  10. springMVC怎么改变form的提交方式为put或者delete

    想着练习一下创建restful风格的网站呢,结果发现在jsp页面上并不能灵活使用put和delete提交方式.下面我的解决办法 一. form 只支持post和get两种提交方式,只支持get提交方式 ...