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

    1. 使用大道科技的EASY-DSP5509开发板,测试第一个例程,DSP_easy5509\Code-Easy5509\EX01_XF\XF 2. 直接编译,报出错误,在Problems窗口错误指示 ...

  2. python删除文本中的所有空字符

    import re import os input_path = 'G:/test/aa.json' output_path ='G:/test/bb.json' with open(input_pa ...

  3. gitlab-登录账户遇到ERROR: Permission to XXX.git denied to user报错怎么办

    碰到这个问题就意味着没有访问账户的权限,没有把访问电脑与访问账户用ssh_key关联起来,解决流程: 1.查看本地是否有ssh_key 笔者用的是git bash来输入命令 ls -al ~/.ssh ...

  4. Python字符串操作大全(非常全!!!)

    1. python编程里字符串的内置方法(非常全) capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) 将字符串居 ...

  5. 了解Python控制流语句——break 语句

    这篇文章主要介绍了详解Python中break语句的用法,是Python入门的呼出知识,需要的朋友可以参考下,python基础系列教程之-Python break语句 跳出循环 break 语句用以中 ...

  6. 本地矩阵(Local Matrix)

    本地矩阵具有整型的行.列索引值和双精度浮点型的元素值,它存储在单机上.MLlib支持稠密矩阵DenseMatrix和稀疏矩阵Sparse Matrix两种本地矩阵,稠密矩阵将所有元素的值存储在一个列优 ...

  7. NOIP2012 普及组真题 4.13校模拟

    考试状态: 我今天抽签看了洛谷的… 这我能怂???凶中带吉,我怕考试??我!不!怕! 看着整个机房的男同学们,我明白我是不会触发我的忌了.很好,开刷. A. [NOIP2012普及组真题] 质因数分解 ...

  8. ajax获取动态列表数据后的分页问题

    ajax获取动态列表数据后的分页问题 这是我在写前台网站时遇到的一个分页问题,由于数据是通过ajax的方式来请求得到的,如果引入相应的js文件来做分页,假如只是静态的填放数据到列表各项内容中(列表条数 ...

  9. Thunder团队第三周 - Scrum会议7

    Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:胡佑蓉 工作照片: 邹双黛在照相,所以图片中没有该同学. 参会成员: 王航:http://www.cnblo ...

  10. Beta阶段项目展示博客

    Beta阶段项目展示 团队成员的简介 详细见团队简介 角色 姓名 照片 项目经理,策划 游心 策划 王子铭 策划 蔡帜 美工 赵晓宇 美工 王辰昱 开发.架构师 解小锐 开发 陈鑫 开发 李金奇 开发 ...