前言

为实现播放器全屏竖屏切换,还可锁住横屏,解锁后又可以跟随传感器变化。


正文

方法一:通过控制android:screenOrientation属性控制横竖屏

1.使用 SCREEN_ORIENTATION_SENSOR 参数设置其可以跟随传感器

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

2.当全屏时点击锁住,使用  SCREEN_ORIENTATION_LOCKED 锁住屏幕

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);

3.点击解锁,再设置为跟随传感器

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

这时候就有一个新的问题给大家,如果要实现点击播放器放大按钮,变成全屏,全屏后还可以跟随传感器变化,大家会怎么做?

你可能会想使用 SCREEN_ORIENTATION_LANDSCAPE 使其横屏,接着设置为跟随传感器 ,也就是以下两行代码。

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

可是结果总是这么不尽如人意。点击"开启旋转"会发现旋转成横屏后会自动又旋回竖屏(因为传感器是读取你现在的手机状态),显而易见,这种体验很不好。

所以我们就有了方法二

方法二:通过监听屏幕旋转角度控制横竖屏

前期配置:

AndroidManifest.xml

android:configChanges="orientation|screenSize">

使其不会重新调用onCreate方法,而是调用onConfigurationChanged,避免出现奇怪的问题。

基础类:

别看代码多,直接拷去用就好

package com.aliyun.vodplayerview.utils;import android.content.Context;
import android.hardware.SensorManager;
import android.view.OrientationEventListener;/** Copyright (C) 2010-2018 Alibaba Group Holding Limited.*//*** 屏幕方向监听类*/
public class OrientationWatchDog {private static final String TAG = OrientationWatchDog.class.getSimpleName();private Context mContext;//系统的屏幕方向改变监听private OrientationEventListener mLandOrientationListener;//对外的设置的监听private OnOrientationListener mOrientationListener;//上次屏幕的方向private Orientation mLastOrientation = Orientation.Port;/*** 屏幕方向*/private enum Orientation {/*** 竖屏*/Port,/*** 横屏*/Land}public OrientationWatchDog(Context context) {mContext = context.getApplicationContext();}/*** 开始监听*/public void startWatch() {VcPlayerLog.e(TAG, "startWatch");if (mLandOrientationListener == null) {mLandOrientationListener = new OrientationEventListener(mContext,SensorManager.SENSOR_DELAY_NORMAL) {@Overridepublic void onOrientationChanged(int orientation) {//这里的|| 和&& 不能弄错!!//根据手机的方向角度计算。在90和180度上下10度的时候认为横屏了。//竖屏类似。boolean isLand = (orientation < 100 && orientation > 80)|| (orientation < 280 && orientation > 260);boolean isPort = (orientation < 10 || orientation > 350)|| (orientation < 190 && orientation > 170);if (isLand) {if (mOrientationListener != null) {mOrientationListener.changedToLandScape(mLastOrientation == Orientation.Port);}mLastOrientation = Orientation.Land;} else if (isPort) {if (mOrientationListener != null) {mOrientationListener.changedToPortrait(mLastOrientation == Orientation.Land);}mLastOrientation = Orientation.Port;}}};}mLandOrientationListener.enable();}/*** 结束监听*/public void stopWatch() {if (mLandOrientationListener != null) {mLandOrientationListener.disable();}}/*** 销毁监听*/public void destroy() {stopWatch();mLandOrientationListener = null;}/*** 屏幕方向变化事件*/public interface OnOrientationListener {/*** 变为Land** @param fromPort 是否是从竖屏变过来的*/void changedToLandScape(boolean fromPort);/*** 变为Port** @param fromLand 是否是从横屏变过来的*/void changedToPortrait(boolean fromLand);}/*** 设置屏幕方向变化事件** @param l 事件监听*/public void setOnOrientationListener(OnOrientationListener l) {mOrientationListener = l;}}

使用方法:

1.实现OnOrientationListener接口,将旋转时需要实现的操作放进去

  界面:

  MainAcitivity:

package com.eddie.screenorientationdemo;import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;import com.eddie.screenorientation.OrientationWatchDog;public class MainActivity extends AppCompatActivity implements OrientationWatchDog.OnOrientationListener {TextView mTvStartSpan;TextView mTvStopSpan;/*** 监听类*/private OrientationWatchDog mOrientationWatchDog;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTvStartSpan = findViewById(R.id.tv_start_span);mTvStopSpan = findViewById(R.id.tv_stop_span);initOrientationWatchdog();mTvStartSpan.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mOrientationWatchDog != null) {mOrientationWatchDog.startWatch();}}});mTvStopSpan.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mOrientationWatchDog != null) {mOrientationWatchDog.stopWatch();}}});}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);}@Overridepublic void changedToLandScape(boolean fromPort) {//如果不是从竖屏变过来,也就是一直是横屏的时候,就不用操作了if (!fromPort) {return;}this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}@Overridepublic void changedToPortrait(boolean fromLand) {//如果没有转到过横屏,就不让他转了。防止竖屏的时候点横屏之后,又立即转回来的现象if (!fromLand) {return;}this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);}/*** 初始化屏幕方向监听器。用来监听屏幕方向。结果通过OrientationListener回调出去。*/private void initOrientationWatchdog() {mOrientationWatchDog = new OrientationWatchDog(this);mOrientationWatchDog.setOnOrientationListener(this);}
}

2.初始化监听器

 /*** 初始化屏幕方向旋转。用来监听屏幕方向。结果通过OrientationListener回调出去。*/private void initOrientationWatchdog() {final Context context = getContext();mOrientationWatchDog = new OrientationWatchDog(context);mOrientationWatchDog.setOnOrientationListener(new InnerOrientationListener(this));}

3.在你需要跟随传感器变化的地方,开启监听器

if (mOrientationWatchDog != null) {mOrientationWatchDog.startWatch();
}

 4.别忘了在不使用的时候关闭监听器

if (mOrientationWatchDog != null) {mOrientationWatchDog.stopWatch();
}

源码: github

借鉴阿里云播放器源码

【Android】android开发---实现屏幕旋转的两种方法相关推荐

  1. hdmi 屏幕旋转 树莓派_树莓派屏幕旋转的两种方法

    标题中的两种方法,实际是对应两种情况.之所以存在两种情况,原因在于现在的(2018.2.4)的raspbian之中,存在一个实验性质的openGL驱动,该驱动能够提供更好的图形性能,但是暂时还不稳定. ...

  2. 【错误记录】NDK 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | Android Studio 配置外部 so 动态库两种方法 )

    文章目录 一.报错信息 二.解决方案 ( Android Studio 配置外部 so 动态库两种方法 ) 1.jniLibs 目录存放 2.libs 目录存放 一.报错信息 外部引用 so 动态库 ...

  3. 将uni-app打包的H5放在 Android程序中在 webview 显示的两种方法

    将uni-app打包的H5放在 Android程序中在 webview 显示的两种方法 前言 Hash History 完事 前言 之前有个项目要同时做小程序和APP,本着节省时间的想法,研究了下un ...

  4. XP计算机调整对比度,Win7系统调节显示器屏幕对比度的两种方法【图文】

    win7系统开机后或者使用过程中,有时候我们会觉得电脑显示器的对比度不合适,需要进行调整,很多朋友不知道怎么调节显示器屏幕对比度?其实调节显示器屏幕对比度的方法比较简单,而且调节出一个合适的屏幕对比度 ...

  5. Wordpress开发 - 获取作者头像的两种方法

    写在前面 今天又被一个头像坑搞惨了,一般我们获取作者的信息是都需要在循环判断中才可以使用的!比如获取作者名称 <?php the_author(); ?> .如果没有在 <?php ...

  6. android判断应用是否回到桌面的两种方法

    有时候需要判断APP是否被切换到后台,然后做相应处理,如显示悬浮窗等.怎么判断呢,有两种方法: 第一种: /*** 判断当前界面是否是桌面*/private boolean isHome() {Str ...

  7. qt 加载 图片旋转_QT 实现图片旋转的两种方法

    第一种方案 使用 QPixmap 的 transformed 函数来实现旋转,这个函数默认是以图片中心为旋转点,不能设置旋转的中心点,使用如下: QMatrix matrix; matrix.rota ...

  8. unity 2D游戏开发 制作帧动画的两种方法

    本小主在这里给大家分享一下unity 2D游戏开发中制作帧动画的两种方法. 比较简单,一学即会. 方法一: 是用代码控制: 先创建一个2D工程.导入图片资源,并设置texture的texture ty ...

  9. QT 屏幕旋转的两种方式

    1.方式一: #include "mainwindow.h" #include <QApplication> #include <QGraphicsView> ...

最新文章

  1. 软件定义汽车:本质并行化的有效平台
  2. K:java中的序列化与反序列化
  3. overflow与min-width
  4. HDOJ1871 无题
  5. 运行 composer update,提示 Allowed memory size of bytes exhausted
  6. 带你理清 Java 混乱的日志体系 - log4j、logback、log4j2、jcl、SLFJ 究竟是啥关系?
  7. Python re module的使用
  8. 有效运维的 on-call 机制
  9. Java8 Stream详解~排序:sorted
  10. 指定JDK版本运行Tomcat
  11. Python 进阶——重访 list
  12. 【深度优先搜索/树】计蒜客:族谱
  13. Dedecms会员中心注入漏洞
  14. NOIp2013 车站分级 【拓扑排序】By cellur925
  15. kafka+线程池+Runnable
  16. 洛谷 P3951 小凯的疑惑
  17. hdu 1520 树形dp入门
  18. 解决Maven项目pom文件中出现的错误:“Missing artifact oracle:ojdbc7:jar:12.1.0.2.0:compile“
  19. Axure RP 9
  20. 中国国际电子商务中心与易观分析联合发布:2021年4季度全国网络零售发展指数同比增长0.6%

热门文章

  1. 配置MySQL字符集教程
  2. swiper 自定义分页器显示_Swiper自定义分页器使用详解
  3. 要将“China“译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母。
  4. 判断链表是否有环-js
  5. Java设计模式:23种设计模式全面解析,墙都不扶就服你
  6. 安达发APS高级计划与排产解决方案
  7. 游戏《部落战争》clash of clans 就是残酷世界的真实写照
  8. LeetCode: 121. 买卖股票的最佳时机(C++)
  9. tomcat + spring mvc 原理(一):tomcat原理综述和静态架构
  10. 2012年10月23日