android调用setRequestedOrientation之后

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

时间: 2024-11-06 03:51:10

android调用setRequestedOrientation之后的相关文章

Android调用系统相机、自定义相机、处理大图片

Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人SurfaceView出现黑屏的原因. Android应用拍照的两种方式,下面为两种形式的Demo展示出来的效果.    知识点: 一.调用系统自带的相机应用 二.自定义我们自己的拍照界面 三.关于计算机解析图片原理(如何正确加载图片到Android应用中) 所需

Android调用WebView

mWebView.setWebViewClient(new WebViewClient(){                           public boolean shouldOverrideUrlLoading(WebView view, String url) {                               view.loadUrl(url);                               return true;                  

Lua学习 1) —— Android调用变量取值与赋值

2014-07-08 Lua脚本语言,嵌入在App中扩展开发是很不错的. 关于Android与Lua的环境搭配,我直接下载别人编好的.so与.jar(放到libs下就好了) 下面简单介绍一下Android调用Lua中的变量以及赋值 LuaState mLuaState; mLuaState = LuaStateFactory.newLuaState(); mLuaState.openLibs();//加载库 mLuaState.LdoString("x = 101");//执行一段lu

Android调用gallery获取图片

从gallery中获取图片 步骤: 步骤一: // 激活系统图库应用,选择一张图片 Intent intent = new Intent(); // 活动操作:选择一个项目从数据,返回被选中 intent.setAction(Intent.ACTION_PICK); // 设置意图的类型 intent.setType("image/*"); // 设置开启意图 // 设置的是有返回值的意图开启需要重写onActivityResult startActivityForResult(int

解决android调用IIS Express中的WCF服务时,出现错误400问题

IIS Express仅支持localhost主机名地址访问. 找到IIS Express Config文件下的 applicationhost.confi   修改配置 再来调试android应用,发下已经成功调用 解决android调用IIS Express中的WCF服务时,出现错误400问题,布布扣,bubuko.com

Android - Android调用JNI方法 及 代码

Android调用JNI方法 及 代码 本文地址: http://blog.csdn.net/caroline_wendy JNI: Java Native Interface, 实现Java和C/C++的互通. 在Android上使用JNI的方法. 时间:2014.9.3 环境: 必须使用标准Eclipse, 安装Android的环境, 才可以使用NDT插件. Eclipse Standard/SDK Version: Luna Release (4.4.0); Android: ADT-23

Android 调用webService(.net平台)

什么是webservice? Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布式的互操作的应用程序.Web   Service所使用的是Internet上统一.开放的标准,如HTTP.XML.SOAP(简单对象访问协议).WSDL(webservice描述语言)等,所以Web   Service可以在任何支持这些标准的环境(Windows,Lin

android 调用系统相机获取图片、调用系统相册获取图片,并对图片进行截取

打开系统相册获取图片并截取,代码相对简单 1 Intent intent = new Intent(Intent.ACTION_GET_CONTENT,null); 2 intent.setType("image/*"); 3 intent.putExtra("crop", "true"); 4 5 //WIDTH 和 HEIGHT指的是截取框的宽高比例,如设WIDTH = 1,HEIGHT = 1,截取框就为正方形 6 intent.putEx

android调用第三方库——第一篇 (转载)

转自:http://blog.csdn.net/jiuyueguang/article/details/9447245 版权声明:本文为博主原创文章,未经博主允许不得转载. 0:前言: 这两天一直在研究用android的jni调用第三方库,上网搜方法,但是都是泛泛而谈,没有demo,经过我几番折磨,写了n多的 helloword工程,总是不成功,工程名字也就由helloowrd转到shithelloword再转到fuckhelloword再转到 bitchhelloword再转到ganhello