最近开发Android Camera相关的程序,被屏幕旋转搞得头大,一方面得考虑屏幕旋转后布局的变化,另一方面得搞清楚屏幕的旋转方向、角度与Camera的Preview角度的关系。本来通过重载Activity的onConfigurationChanged方法,可以检测到屏幕旋转,但发现有一个问题,它只能检测水平方向与垂直方向的切换,无法检测180度的跳转(例如:水平方向突然转180度到水平方向),所以最后不得不换成OrientationEventListener方法来解决问题。在这里分享下经验,并就此顺便总结下Android开发中屏幕旋转的处理吧。

1. 不做任何处理的情况下

如果没有针对性地做任何处理的话,默认情况下,当用户手机的重力感应器打开后,旋转屏幕方向,会导致app的当前activity发生onDestroy-> onCreate,会重新构造当前activity和界面布局,很多横屏/竖屏的布局如果没有很好的设计的话,转换为竖屏/横屏后,会显示地很难看。

如果想很好地支持屏幕旋转,则建议在res中建立layout-land和layout-port两个文件夹,把横屏和竖屏的布局文件放入对应的layout文件夹中。

2. 如何设置固定的屏幕方向

在AndroidManifest.xml对应的 activity 属性中,添加:

1
2
android:screenOrientation="landscape"  //横屏
android:screenOrientation="portrait"   //竖屏

那么,默认的情况下,应用启动后,会固定为指定的屏幕方向,即使屏幕旋转,Activity也不会出现销毁或者转向等任何反应。

3. 强制开启屏幕旋转效果

如果用户的手机没有开启重力感应器或者在AndroidManifest.xml中设置了android:screenOrientation,默认情况下,该Activity不会响应屏幕旋转事件。如果在这种情况下,依然希望Activity能响应屏幕旋转,则添加如下代码:

1
2
// activity的 onCreate 函数中
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

4. 屏幕旋转时,不希望activity被销毁

如果希望捕获屏幕旋转事件,并且不希望activity 被销毁,方法如下:

(1)在AndroidManifest.xml对应的activity属性中,添加:

1
android:configChanges="orientation|screenSize"

(2)在对应的activity中,重载函数onConfigurationChanged

1
2
3
4
@Override
public voidonConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

在该函数中可以通过两种方法检测当前的屏幕状态:

第一种:

判断newConfig是否等于Configuration.ORIENTATION_LANDSCAPE,Configuration.ORIENTATION_PORTRAIT

当然,这种方法只能判断屏幕是否为横屏,或者竖屏,不能获取具体的旋转角度。

第二种:

调用this.getWindowManager().getDefaultDisplay().getRotation();

该函数的返回值,有如下四种:

Surface.ROTATION_0,Surface.ROTATION_90,Surface.ROTATION_180,Surface.ROTATION_270

其中,Surface.ROTATION_0 表示的是手机竖屏方向向上,后面几个以此为基准依次以顺时针90度递增。

(3) 这种方法的Bug

最近发现这种方法有一个Bug,它只能一次旋转90度,如果你突然一下子旋转180度,onConfigurationChanged函数不会被调用。

5. 实时判断屏幕旋转的每一个角度

上面说的各种屏幕旋转角度的判断至多只能判断 0,90,180,270 四个角度,如果希望实时获取每一个角度的变化,则可以通过OrientationEventListener 来实现。

使用方法:

(1)创建一个类继承OrientationEventListener

1
2
3
4
5
6
7
8
9
public class MyOrientationDetector extends OrientationEventListener{
    public MyOrientationDetector( Context context ) {
        super(context );
    }
    @Override
    public void onOrientationChanged(int orientation) {
        Log.i("MyOrientationDetector ","onOrientationChanged:"+orientation);
    }
}

(2)开启和关闭监听

可以在 activity 中创建MyOrientationDetector 类的对象,注意,监听的开启的关闭,是由该类的父类的 enable() 和 disable() 方法实现的。

因此,可以在activity的 onResume() 中调用MyOrientationDetector 对象的 enable方法,在 onPause() 中调用MyOrientationDetector 对象的 disable方法来完车功能。

(3)监测指定的屏幕旋转角度

MyOrientationDetector类的onOrientationChanged 参数orientation是一个从0~359的变量,如果只希望处理四个方向,加一个判断即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
    return;  //手机平放时,检测不到有效的角度
}
//只检测是否有四个角度的改变
if( orientation > 350 || orientation< 10 ) { //0度
     orientation = 0;
}   
else if( orientation > 80 &&orientation < 100 ) { //90度
    orientation= 90;
}
else if( orientation > 170 &&orientation < 190 ) { //180度
    orientation= 180;
}
else if( orientation > 260 &&orientation < 280  ) { //270度
    orientation= 270;
}
else {
    return;
}
Log.i("MyOrientationDetector ","onOrientationChanged:"+orientation);

本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/1301209,如需转载请自行联系原作者

Android开发实践:屏幕旋转的处理相关推荐

  1. 【Android】android开发---实现屏幕旋转的两种方法

    前言 为实现播放器全屏竖屏切换,还可锁住横屏,解锁后又可以跟随传感器变化. 正文 方法一:通过控制android:screenOrientation属性控制横竖屏 1.使用 SCREEN_ORIENT ...

  2. Xamarin.Android开发实践(十七)

    Xamarin.Android开发实践(十七) 原文:Xamarin.Android开发实践(十七) Xamarin.Android之定位 一.前言 打开我们手中的应用,可以发现越来越多的应用使用了定 ...

  3. Xamarin.Android开发实践(十四)

    原文:Xamarin.Android开发实践(十四) Xamarin.Android之ListView和Adapter 一.前言 如今不管任何应用都能够看到列表的存在,而本章我们将学习如何使用Xama ...

  4. Xamarin.Android开发实践(一)

    原文:Xamarin.Android开发实践(一) 一.准备工作 1.创建一个空的解决方案,并命名为Phoneword 2.右击解决方案 新建->新建项目 并命名为Phoneword_Droid ...

  5. Android开发实践:Java层与Jni层的数组传递

    Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni ...

  6. iOS开发中屏幕旋转(二)

    Morris_ 2019.04.11 前面有总结过一些在开发中遇到的屏幕旋转的基础知识. 一.设置应用支持的转屏方向 设置方式 00x1 在TARGET->General->Deploym ...

  7. IOS(iphone,ipad,itouch)开发 之 屏幕旋转

    关于IOS开发中屏幕旋转的问题. 看过很多大牛的文章,都写过类似的,这里我只写一下常用的几个函数的具体用法. 首先是 - (BOOL)shouldAutorotateToInterfaceOrient ...

  8. 设置Android默认锁定屏幕旋转

    /*********************************************************************************** 设置Android默认锁定屏幕 ...

  9. android并发命令,Android开发实践:基于命令模式的异步任务线程

    关于Android的异步操作,我在文章<Android开发实践:线程与异步任务>中介绍了两种方法,一种是采用线程,另一种是采用AsyncTask,今天再深入探讨下另一种模型:命令式的异步任 ...

最新文章

  1. Xtrabackup实现数据的备份与恢复
  2. AI设计的新启发 | 什么是用户体验中台?
  3. 用行为级描述方式实现一个加法器电路(基于ISE的设计)(2输入1位全加器电路)
  4. AES和TKIP的区别
  5. 文件描述符fd是什么?
  6. 压缩信息立方体和集合技术内幕
  7. 【洛谷P1378】油滴扩展
  8. 713C - 如何进入一个研究领域
  9. 每日一题 字典序的第K小数字
  10. mumu模拟器cpu设置_网易mc怎么提高fps
  11. note2 android4.3,三星N7100/note2官方4.3原版线刷版N7100ZCUENB1
  12. 据说这是最难学的十大编程语言 Java排第三
  13. 认同和确定性矩阵(Ralph Stacey's Agreement and Certainty Matrix)-译
  14. BI神器Power Query(3)-- PQ从表格导入数据
  15. m.634226.c.html,a00614.html
  16. 【JAVA】科研信息管理系统
  17. KVS+keepalived群集
  18. 赢在云端:VMware跨云架构,让“云”卷“云”舒自由可控!——访VMware公司大中华区高级技术总监李刚
  19. Linux之《荒岛余生》(三)内存篇
  20. 基于 Android 系统手机通讯录管理软件【100010322】

热门文章

  1. C Primer Plus (第五版) 第十章 数组和指针 编程练习
  2. .net简单算法实现无限级分类(一)
  3. Android多线程:这是一份全面 详细的线程池(ThreadPool)讲解教程
  4. Python标准模块--asyncio
  5. 一些C实现的数学函数实现(估算)
  6. Linux 配置ip地址
  7. HTTP 错误 404.3 - Forbidden
  8. 关于while 和if
  9. SQL的不合理有效性
  10. WEB应用常见15种安全漏洞一览