【Android】android开发---实现屏幕旋转的两种方法
前言
为实现播放器全屏竖屏切换,还可锁住横屏,解锁后又可以跟随传感器变化。
正文
方法一:通过控制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开发---实现屏幕旋转的两种方法相关推荐
- hdmi 屏幕旋转 树莓派_树莓派屏幕旋转的两种方法
标题中的两种方法,实际是对应两种情况.之所以存在两种情况,原因在于现在的(2018.2.4)的raspbian之中,存在一个实验性质的openGL驱动,该驱动能够提供更好的图形性能,但是暂时还不稳定. ...
- 【错误记录】NDK 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | Android Studio 配置外部 so 动态库两种方法 )
文章目录 一.报错信息 二.解决方案 ( Android Studio 配置外部 so 动态库两种方法 ) 1.jniLibs 目录存放 2.libs 目录存放 一.报错信息 外部引用 so 动态库 ...
- 将uni-app打包的H5放在 Android程序中在 webview 显示的两种方法
将uni-app打包的H5放在 Android程序中在 webview 显示的两种方法 前言 Hash History 完事 前言 之前有个项目要同时做小程序和APP,本着节省时间的想法,研究了下un ...
- XP计算机调整对比度,Win7系统调节显示器屏幕对比度的两种方法【图文】
win7系统开机后或者使用过程中,有时候我们会觉得电脑显示器的对比度不合适,需要进行调整,很多朋友不知道怎么调节显示器屏幕对比度?其实调节显示器屏幕对比度的方法比较简单,而且调节出一个合适的屏幕对比度 ...
- Wordpress开发 - 获取作者头像的两种方法
写在前面 今天又被一个头像坑搞惨了,一般我们获取作者的信息是都需要在循环判断中才可以使用的!比如获取作者名称 <?php the_author(); ?> .如果没有在 <?php ...
- android判断应用是否回到桌面的两种方法
有时候需要判断APP是否被切换到后台,然后做相应处理,如显示悬浮窗等.怎么判断呢,有两种方法: 第一种: /*** 判断当前界面是否是桌面*/private boolean isHome() {Str ...
- qt 加载 图片旋转_QT 实现图片旋转的两种方法
第一种方案 使用 QPixmap 的 transformed 函数来实现旋转,这个函数默认是以图片中心为旋转点,不能设置旋转的中心点,使用如下: QMatrix matrix; matrix.rota ...
- unity 2D游戏开发 制作帧动画的两种方法
本小主在这里给大家分享一下unity 2D游戏开发中制作帧动画的两种方法. 比较简单,一学即会. 方法一: 是用代码控制: 先创建一个2D工程.导入图片资源,并设置texture的texture ty ...
- QT 屏幕旋转的两种方式
1.方式一: #include "mainwindow.h" #include <QApplication> #include <QGraphicsView> ...
最新文章
- 软件定义汽车:本质并行化的有效平台
- K:java中的序列化与反序列化
- overflow与min-width
- HDOJ1871 无题
- 运行 composer update,提示 Allowed memory size of bytes exhausted
- 带你理清 Java 混乱的日志体系 - log4j、logback、log4j2、jcl、SLFJ 究竟是啥关系?
- Python re module的使用
- 有效运维的 on-call 机制
- Java8 Stream详解~排序:sorted
- 指定JDK版本运行Tomcat
- Python 进阶——重访 list
- 【深度优先搜索/树】计蒜客:族谱
- Dedecms会员中心注入漏洞
- NOIp2013 车站分级 【拓扑排序】By cellur925
- kafka+线程池+Runnable
- 洛谷 P3951 小凯的疑惑
- hdu 1520 树形dp入门
- 解决Maven项目pom文件中出现的错误:“Missing artifact oracle:ojdbc7:jar:12.1.0.2.0:compile“
- Axure RP 9
- 中国国际电子商务中心与易观分析联合发布:2021年4季度全国网络零售发展指数同比增长0.6%
热门文章
- 配置MySQL字符集教程
- swiper 自定义分页器显示_Swiper自定义分页器使用详解
- 要将“China“译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母。
- 判断链表是否有环-js
- Java设计模式:23种设计模式全面解析,墙都不扶就服你
- 安达发APS高级计划与排产解决方案
- 游戏《部落战争》clash of clans 就是残酷世界的真实写照
- LeetCode: 121. 买卖股票的最佳时机(C++)
- tomcat + spring mvc 原理(一):tomcat原理综述和静态架构
- 2012年10月23日