美文网首页Android开发经验谈Android开发Android技术知识
【Android】 从头搭建视频播放器(4)——屏幕旋转处理

【Android】 从头搭建视频播放器(4)——屏幕旋转处理

作者: 牧秦丶 | 来源:发表于2017-11-03 09:56 被阅读366次

    转载请注明出处http://www.jianshu.com/p/eb4451923172

    项目代码地址:https://github.com/Android-Jungle/android-jungle-mediaplayer
     

    1、思路

            作为一款用户体验比较好的播放器,针对屏幕旋转来做适配处理是必不可少的,我们可以通过 Android SDK 提供的 OrientationEventListener 来进行处理。在屏幕旋转时,会回调到 onOrientationChanged(int orientation) 方法中,我们在这里判断旋转的角度,然后调节 Activity 的 ScreenOrientation,即可做到视频画面随手机旋转而旋转的效果。

    2、OrientationEventListener

            OrientationEventListener 其实就是一个帮助类,它内部有一个 SensorEventListener,通过对手机传感器的监听处理(SensorManager),而做到屏幕旋转的判断。它的主要的方法如下

    方法 特性
    OrientationEventListener(context) 构造函数
    enable() 启用监听,一般我们需要监听的时候调用它
    disable() 停止监听,一般在 Activity 销毁之前或者不再需要监听旋转的时候调用它
    onOrientationChanged(orientation) 屏幕发生了旋转

    3、onOrientationChanged(int orientation)

            这个方法是最重要的一个方法了,我们可以根据所传入的参数 orientation 来判断当前屏幕所在的角度。orientation 所代表的具体值如下:

    Orientations

            其实就是拿手机顺时针旋转,依次将 orientation 增大 90 的过程。我们在 onOrientationChanged 回调中,根据 orientation 所处的区间,可以轻松得到应该请求的屏幕 Orientation。为了优化灵敏度,我们为每个区间的上下限个增加了 10 。具体计算过程如下:

    处理 Orientation

            得到了当前屏幕角度下 Activity 应该需要的 ScreenOrientation,我们就可以通过 Activity.setRequestedOrientation(int requestedOrientation) 方法来进行 Activity 屏幕角度的更改,然后整个 View 的布局就会随之更新,我们的视频画面也能得到相应的更新。

    4、Activity 的处理

    4.1、请求更改 Activity ScreenOrientation

            具体代码如下:

    SwitchScreenOrientation

            可以看到我们在全屏模式下为 Activity 添加了 FLAG_FULLSCREEN 标识,让其处于全屏模式。在切换到非全屏模式的时候清除该标记即可。

    4.2、Activity 的声明

            为了灵活处理屏幕旋转 + 全屏半屏的切换,而不销毁 Activity,我们的 Activity 必须在声明的时候,在 configChanges 里面加上 orientation 标记:

    Activity声明

    4.3、处理 onConfigurationChanged

            当调用 Activity.setRequestedOrientation 方法之后,可以在 Activity.onConfigurationChanged(Configuration newConfig) 方法中进行处理。newConfig.orientation 就是新的屏幕角度,它应该是 ActivityInfo.SCREEN_ORIENTATION_XXX 中的一个值。在这里我们应该做的操作有:

    • 调整视频播放区域的大小及布局——通过 setLayoutParams 实现
    • 按全屏/半屏状态更新相关 UI——比如各个按钮、一些界面细节的处理

            好在 Android 的各种 Layout 可以灵活的做到布局更新,我们只需要为视频播放器 StrawMediaPlayer 的跟 ViewGroup 做新的排布参数,其子 View 都会按相应的布局规则得到刷新,非常方便。

    5、检测系统 “屏幕自动旋转” 开关

            为了优化体验,我们可以检测系统的 “屏幕自动旋转” 开关,在这个开关关闭的时候,我们不进行屏幕旋转的相关处理。判断这个开关状态的代码如下:

    /**
     * 判断是否开启了 “屏幕自动旋转”
     */
    public static boolean isScreenAutoRotate(Context context) {
        int gravity = 0;
        try {
            gravity = Settings.System.getInt(context.getContentResolver(),
                    Settings.System.ACCELEROMETER_ROTATION);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
    
        return gravity == 1;
    }
    

    6、代码片段

    /**
     * ScreenOrientationSwitcher.java
     *
     * @author arnozhang
     * @email  zyfgood12@163.com
     * @date   2015.9.25
     */
    public class ScreenOrientationSwitcher extends OrientationEventListener {
    
        private static final long MAX_CHECK_INTERVAL = 3000;
    
    
        public static interface OnChangeListener {
            void onChanged(int requestedOrientation);
        }
    
    
        private WeakReference<Context> mContextRef;
        private boolean mIsSupportGravity = false;
        private int mCurrOrientation = ORIENTATION_UNKNOWN;
        private long mLastCheckTimestamp = 0;
        private OnChangeListener mChangeListener;
    
    
        public ScreenOrientationSwitcher(Context context) {
            super(context);
            mContextRef = new WeakReference<Context>(context);
        }
    
        public ScreenOrientationSwitcher(Context context, int rate) {
            super(context, rate);
            mContextRef = new WeakReference<Context>(context);
        }
    
        public void setChangeListener(OnChangeListener listener) {
            mChangeListener = listener;
        }
    
        public int getCurrOrientation() {
            return mCurrOrientation;
        }
    
        @Override
        public void onOrientationChanged(int orientation) {
            Context context = mContextRef.get();
            if (context == null || !(context instanceof Activity)) {
                return;
            }
    
            long currTimestamp = System.currentTimeMillis();
            if (currTimestamp - mLastCheckTimestamp > MAX_CHECK_INTERVAL) {
                mIsSupportGravity = MiscUtils.isScreenAutoRotate(context);
                mLastCheckTimestamp = currTimestamp;
            }
    
            if (!mIsSupportGravity) {
                return;
            }
    
            if (orientation == ORIENTATION_UNKNOWN) {
                return;
            }
    
            int requestOrientation = ORIENTATION_UNKNOWN;
            if (orientation > 350 || orientation < 10) {
                requestOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
            } else if (orientation > 80 && orientation < 100) {
                requestOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            } else if (orientation > 260 && orientation < 280) {
                requestOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            } else {
                return;
            }
    
            if (requestOrientation == mCurrOrientation) {
                return;
            }
    
            boolean needNotify = mCurrOrientation != ORIENTATION_UNKNOWN;
            mCurrOrientation = requestOrientation;
    
            if (needNotify) {
                if (mChangeListener != null) {
                    mChangeListener.onChanged(requestOrientation);
                } else {
                    Activity activity = (Activity) context;
                    activity.setRequestedOrientation(requestOrientation);
                }
            }
        }
    }
    
    

    相关文章

      网友评论

        本文标题:【Android】 从头搭建视频播放器(4)——屏幕旋转处理

        本文链接:https://www.haomeiwen.com/subject/tlnzpxtx.html