前言

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


正文

方法一:通过控制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) {                @Override                public 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;    @Override    protected 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() {            @Override            public void onClick(View v) {                if (mOrientationWatchDog != null) {                    mOrientationWatchDog.startWatch();                }            }        });        mTvStopSpan.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (mOrientationWatchDog != null) {                    mOrientationWatchDog.stopWatch();                }            }        });    }    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);    }    @Override    public void changedToLandScape(boolean fromPort) {        //如果不是从竖屏变过来,也就是一直是横屏的时候,就不用操作了        if (!fromPort) {            return;        }        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    }    @Override    public 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

借鉴阿里云播放器源码

更多相关文章

  1. Android(安卓)加速度传感器(G-Sensor)
  2. Android(安卓)屏幕的旋转 onConfigurationChanged方法
  3. Android-基本控件(SeekBar 可拖动 滚动条的使用)
  4. android 当环境配置发生变化 例如语言 屏幕变化
  5. Android监听来电和去电的实现方法
  6. Android初级教程小案例之单选框RadioGroup与复选框CheckBox
  7. Android(安卓)电子罗盘--指南针(方向传感器的应用)
  8. Android打开WLAN开关的广播状态监听
  9. Android软键盘弹出,界面整体上移的问题

随机推荐

  1. android 从零单排 第一期 按键显示hellow
  2. android GSM+CDMA基站定位
  3. Android中两个Activity之间的跳转
  4. Android(安卓)NDK的安装。(下一篇是关于 o
  5. 【Android(安卓)开发教程】在服务中执行
  6. Android(安卓)arm linux 系统调用实现
  7. Android(安卓)Bluetooth开发
  8. Android实现发送短信验证码倒计时功能示
  9. 在Ubuntu中获取Android源文件(相关整理&
  10. android多国语言列表