转载请注明出处:【From李诗雨---http://blog.csdn.net/cjm2484836553/article/details/78420172】

不诗意的女程序猿不是好厨师~


【代码下载】:节操播放器在Activity中的使用代码


节操播放器在github的地址:https://github.com/lipangit/JiaoZiVideoPlayer

节操播放器,现在改名叫饺子播放器了,你们发现了吗?
项目中使用到了节操播放器(饺子播放器),还真遇到了不少问题。
今天就在这里来好好地整理总结一下。

【主要内容】
节操播放器在Activity中的使用:
1.节操播放器的简单集成

2.横竖屏切换

    2.1 点击全屏,直接进入到横屏全屏的实现2.2 重力感应下横竖屏切换的实现2.3 重力感应下横竖屏切换不灵敏问题的解决

3.清晰度切换

    3.1 清晰度切换的简单实现3.2 清晰度切换的自定义样式3.3 直播流清晰度切换时,出现灰色闪屏问题的解决

4.沉浸式状态栏

    4.1 沉浸式状态的简单集成4.2 状态栏与布局重叠问题的解决4.3 全屏播放视频时,沉浸式状态栏的问题解决4.4 华为5.0虚拟导航栏引起的问题处理

节操播放器在Fragment的使用

下面就让我们来看看这些七七八八的问题及解决办法吧:

节操播放器在activity中的使用

建议使用第三方库,最好以module的形式导入!
主要原因有二:
①方便修改库中的代码,为我所用
②安全,防止库发生改变后会对自己的代码造成不必要的影响

一、节操播放器的简单集成(这里我们根据github上的内容进行集成)

1.将jiaozivideoplayer以module的形式导入,并关联

2.AndroidManifest中
①添加联网权限

 <uses-permission android:name="android.permission.INTERNET" />

②配置对应的activity(这一步不可忘!),否则横屏时会出问题。

<activity android:name=".MainActivity"android:configChanges="orientation|screenSize|keyboardHidden"android:screenOrientation="portrait"></activity>

2.布局中:

<cn.jzvd.JZVideoPlayerStandardandroid:id="@+id/lsy_video_player"android:layout_width="match_parent"android:layout_height="200dp"/>

3.Acitivity中:

@Override
public void onBackPressed() {if (JZVideoPlayer.backPress()) {return;}super.onBackPressed();
}@Override
protected void onPause() {super.onPause();JZVideoPlayer.releaseAllVideos();
}
 //设置播放器播放地址lsyVideoPlayer.setUp("http://jzvd.nathen.cn/342a5f7ef6124a4a8faf00e738b8bee4/cf6d9db0bd4d41f59d09ea0a81e918fd-5287d2089db37e62345123a1be272f8b.mp4", JZVideoPlayerStandard.SCREEN_LAYOUT_NORMAL, "小孩子");//设置播放器封面Picasso.with(this).load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png").into(lsyVideoPlayer.thumbImageView);

好的,让我们来看下集成效果:

二.横竖屏切换

2.1 点击全屏,直接进入到横屏全屏的实现
刚才我们看到集成的效果,当点击全屏按钮时,切换到的并不是横屏全屏状态。 现在我们的需求是点击全屏按钮时,直接切换到横屏全屏状态,该怎么操作呢?
这个简单,在设置播放器前加两行代码就行了。

JZVideoPlayer.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;  //横向JZVideoPlayer.NORMAL_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;  //纵向

欧了,看下效果(由于是模拟器,所以可能看起来有点晃哈):

2.2 重力感应下横竖屏切换的实现
①首先在初始化播放器时:

 //用于实现重力感应下切换横竖屏sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);sensorEventListener = new JZVideoPlayer.JZAutoFullscreenListener();

②然后在onResume()方法中:

 @Override
protected void onResume() {super.onResume();//播放器重力感应Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(sensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}

③然后在onPause()方法中要注意解注册:

@Override
protected void onPause() {super.onPause();sensorManager.unregisterListener(sensorEventListener);JZVideoPlayer.releaseAllVideos();
}

这个模拟器没法展示重力感应效果了,你可用真机进行测试一下。
确实是可以进行重力感应下的横竖屏切换了,但是不怎么灵敏好用,又要怎么办呢?

2.3 重力感应下横竖屏切换不灵敏问题的解决 这就需要我们来改播放器的源码了。
这里我们都是对JZVideoPlayer这个类进行的操作,具体操作如下:
①自己新定义一个变量来记录旋转的几种状态。

private static int canFullScreen = 0;

②在onClick()中,当fullscreen被点击时:

//退出全屏时,令 canFullScreen = 1;
//进入全屏时,令canFullScreen = 5;
else if (i == R.id.fullscreen) {Log.i(TAG, "onClick fullscreen [" + this.hashCode() + "] ");if (currentState == CURRENT_STATE_AUTO_COMPLETE) return;if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {//quit fullscreenbackPress();canFullScreen = 1;isFullScreenNow = false;//} else {canFullScreen = 5;Log.d(TAG, "toFullscreenActivity [" + this.hashCode() + "] ");onEvent(JCUserAction.ON_ENTER_FULLSCREEN);startWindowFullscreen();isFullScreenNow = true;//}

③在onAutoCompletion()方法中,也添加对canFullScreen的记录:

public void onAutoCompletion() {//加上这句,避免循环播放video的时候,内存不断飙升。Runtime.getRuntime().gc();Log.i(TAG, "onAutoCompletion " + " [" + this.hashCode() + "] ");onEvent(JZUserAction.ON_AUTO_COMPLETE);dismissVolumeDialog();dismissProgressDialog();dismissBrightnessDialog();cancelProgressTimer();onStateAutoComplete();if (currentScreen == SCREEN_WINDOW_FULLSCREEN || currentScreen == SCREEN_WINDOW_TINY) {backPress();//全屏结束恢复状态canFullScreen = 0;}canFullScreen = 0;JZMediaManager.instance().mediaPlayer.release();JZUtils.saveProgress(getContext(), JZUtils.getCurrentUrlFromMap(urlMap, currentUrlMapIndex), 0);}

④在releaseAllVideos()方法中: 令 canFullScreen = 0;

 public static void releaseAllVideos() {if ((System.currentTimeMillis() - CLICK_QUIT_FULLSCREEN_TIME) > FULL_SCREEN_NORMAL_DELAY) {Log.d(TAG, "releaseAllVideos");JZVideoPlayerManager.completeAll();JZMediaManager.instance().positionInList = -1;JZMediaManager.instance().releaseMediaPlayer();canFullScreen = 0;}
}

⑤我们的核心是对autoFullscreen()方法进行修改
主要原理是根据旋转角度,来规定状态
修改后如下模样: (你也可以根据自己对灵敏度的要求,针对角度进行相应的修改)

 public void autoFullscreen(float x) {
//        if (isCurrentPlay()
//                && currentState == CURRENT_STATE_PLAYING
//                && currentScreen != SCREEN_WINDOW_FULLSCREEN
//                && currentScreen != SCREEN_WINDOW_TINY) {
//            if (x > 0) {
//                JZUtils.setRequestedOrientation(getContext(), ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//            } else {
//                JZUtils.setRequestedOrientation(getContext(), ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
//            }
//            onEvent(JZUserAction.ON_ENTER_FULLSCREEN);
//            startWindowFullscreen();
//        }if (isCurrentJZVD() && currentState == CURRENT_STATE_PLAYING) {if (x > 45 && x < 115 && currentScreen != SCREEN_WINDOW_FULLSCREEN && (canFullScreen == 2 || canFullScreen == 4 || canFullScreen == 0 || canFullScreen == 3)) {//左转canFullScreen = 1;onEvent(JZUserAction.ON_ENTER_FULLSCREEN);startWindowFullscreen();JZUtils.getAppCompActivity(getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);} else if (x > 135 && x < 225 && currentScreen == SCREEN_WINDOW_FULLSCREEN && (canFullScreen == 1 || canFullScreen == 3 || canFullScreen == 0)) {//上canFullScreen = 2;backPress();} else if (x > 245 && x < 315 && currentScreen != SCREEN_WINDOW_FULLSCREEN && (canFullScreen == 2 || canFullScreen == 4 || canFullScreen == 0 || canFullScreen == 1)) {//右转canFullScreen = 3;onEvent(JZUserAction.ON_ENTER_FULLSCREEN);startWindowFullscreen();JZUtils.getAppCompActivity(getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);} else if ((x > 315 && x < 360) || (x > 0 && x < 45) && currentScreen == SCREEN_WINDOW_FULLSCREEN && (canFullScreen == 1 || canFullScreen == 3 || canFullScreen == 0)) {//下canFullScreen = 4;backPress();} else if (x > 45 && x < 135 && currentScreen == SCREEN_WINDOW_FULLSCREEN && canFullScreen == 5) {//全屏后恢复自动旋转canFullScreen = 1;} else if (x > 225 && x < 315 && currentScreen == SCREEN_WINDOW_FULLSCREEN && canFullScreen == 5) {//全屏后恢复自动旋转canFullScreen = 3;} else if (x > 135 && x < 225 && currentScreen != SCREEN_WINDOW_FULLSCREEN && (canFullScreen == 1 || canFullScreen == 3 || canFullScreen == 2 || canFullScreen == 5)) {//返回后恢复自动旋转canFullScreen = 2;}}
}

⑥最后JCAutoFullscreenListener也要做相应的修改,修改后如下所示:

//再定义一个变量来记录重力传感器倾斜角度
private static float orientation;public static class JZAutoFullscreenListener implements SensorEventListener {@Overridepublic void onSensorChanged(SensorEvent event) {//可以得到传感器实时测量出来的变化值final float x = event.values[SensorManager.DATA_X];float y = event.values[SensorManager.DATA_Y];float z = event.values[SensorManager.DATA_Z];//过滤掉用力过猛会有一个反向的大数值
//            if (((x > -15 && x < -10) || (x < 15 && x > 10)) && Math.abs(y) < 1.5) {
//                if ((System.currentTimeMillis() - lastAutoFullscreenTime) > 2000) {
//                    if (JCVideoPlayerManager.getCurrentJcvd() != null) {
//                        JCVideoPlayerManager.getCurrentJcvd().autoFullscreen(orientation);
//                    }
//                    if (JZVideoPlayerManager.getCurrentJzvd() != null) {
//                        JZVideoPlayerManager.getCurrentJzvd().autoFullscreen(x);
//                    }
//                    lastAutoFullscreenTime = System.currentTimeMillis();
//                }
//            }float magnitude = (x * x) + (y * y);if (magnitude * 4 >= z * z) {// 屏幕旋转时float OneEightyOverPi = 57.29577957855f;float angle = (float) Math.atan2(-y, x) * OneEightyOverPi;orientation = 90 - Math.round(angle); // normalize to 0 - 359 rangewhile (orientation >= 360) {orientation -= 360;}while (orientation < 0) {orientation += 360;}}if (JZVideoPlayerManager.getCurrentJzvd() != null) {JZVideoPlayerManager.getCurrentJzvd() .autoFullscreen(orientation);}}

这时再次运行代码,你就会发现重力感应下的横竖屏切换就已经很灵敏了。 当然如果还不能满足你的要求,你可以参看上面的步骤再做相应的调整。

三、清晰度切换

3.1 清晰度切换的简单实现
饺子播放器已经帮我们做好了清晰度切换的简单封装,全屏时可进行清晰度的切换。
如果想要实现切换清晰度,我们传播放地址时只要以Map的形式传进去就可以了:

private void initClarityVideoPlayer() {String videoUrl1_biaoqing=  "http://jzvd.nathen.cn/c494b340ff704015bb6682ffde3cd302/64929c369124497593205a4190d7d128-5287d2089db37e62345123a1be272f8b.mp4";String videoUrl2_puqing= "http://jzvd.nathen.cn/342a5f7ef6124a4a8faf00e738b8bee4/cf6d9db0bd4d41f59d09ea0a81e918fd-5287d2089db37e62345123a1be272f8b.mp4";String videoUrl3_gaoqing= "http://jzvd.nathen.cn/f07fa9fddd1e45a6ae1570c7fe7967c1/c6db82685b894e25b523b1cb28d79f2e-5287d2089db37e62345123a1be272f8b.mp4";//播放带清晰度的视频LinkedHashMap map = new LinkedHashMap();map.put("标清", videoUrl1_biaoqing);map.put("普清", videoUrl2_puqing);map.put("高清", videoUrl3_gaoqing);clarityVideoPlayer.setUp(map, 0, JZVideoPlayerStandard.SCREEN_LAYOUT_NORMAL, "全屏时清晰度切换");
}

我们开看一下效果:

你可能会觉得弹出清晰度的popupwidow不好点,又或者你需要其他的效果来显示,

那么,这时候就需要我们来修改饺子播放器的源码了。

3.2 清晰度切换的自定义样式
现在比如我们的需求是实现下图所示的清晰度切换:

如何才能实现这种效果呢?
下面让我们来对饺子播放器的源码做相应的修改:
注:以下的操作都是对饺子播放器的源码库进行操作的
①先找到,清晰度对应的popupwindow所在的布局文件jzlayoutclarity.xml:
修改成现在我们需要的样子

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/video_quality_wrapper_area"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:background="#66000000"
android:orientation="vertical"
/><!--原始的切换清晰度布局-->
<!--<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"-->
<!--android:id="@+id/video_quality_wrapper_area"-->
<!--android:layout_width="80dp"-->
<!--android:layout_height="wrap_content"-->
<!--android:background="@drawable/jz_clarity_popwindow_bg"-->
<!--android:orientation="vertical"-->
<!--android:paddingBottom="16dp"-->
<!--android:paddingTop="10dp" />-->

再修改清晰度item对应的布局,来到jzlayoutclarity_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"><TextViewandroid:id="@+id/video_item"android:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center"android:background="#fff"android:orientation="vertical"android:paddingBottom="8dp"android:paddingLeft="10dp"android:paddingRight="10dp"android:paddingTop="8dp"android:textColor="#000"android:textSize="15sp" />
<!--android:textColor="#FFF"-->
<!--设置清晰度tv的颜色--><Viewandroid:background="#05000000"android:layout_width="match_parent"android:layout_height="1dp"/></LinearLayout><!--原始的item对应的布局-->
<!--<TextView xmlns:android="http://schemas.android.com/apk/res/android"-->
<!--android:id="@+id/video_item"-->
<!--android:layout_width="fill_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:gravity="center"-->
<!--android:orientation="vertical"-->
<!--android:paddingBottom="8dp"-->
<!--android:paddingLeft="10dp"-->
<!--android:paddingRight="10dp"-->
<!--android:paddingTop="8dp"-->
<!--android:textColor="#FFF"-->
<!--android:textSize="14sp" />-->

再添加一个cancel对应的item布局:

<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"><Viewandroid:background="#00000000"android:layout_width="match_parent"android:layout_height="4dp"/><TextView
android:textStyle="bold"
android:id="@+id/video_item"
android:text="Cancel"
android:background="#ffffff"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="8dp"
android:textColor="#000"
android:textSize="16sp" />
<!--android:textColor="#FFF"-->
<!--设置清晰度tv的颜色--></LinearLayout>

②下面在JZVideoPlayerStandard类中的onClick()方法中
做一下修改(修改的主要是popupwindow,包括它的显示位置、大小等)

else if (i == R.id.clarity) {LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);final LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.jz_layout_clarity, null);OnClickListener mQualityListener = new OnClickListener() {public void onClick(View v) {int index = (int) v.getTag();onStatePreparingChangingUrl(index, getCurrentPositionWhenPlaying());clarity.setText(JZUtils.getKeyFromLinkedMap(urlMap, currentUrlMapIndex));for (int j = 0; j < layout.getChildCount(); j++) {//设置点击之后的颜色if (j == currentUrlMapIndex) {//选中设为蓝色
//                            ((TextView) layout.getChildAt(j)).setTextColor(Color.parseColor("#fff85959"));((TextView) (layout.getChildAt(j)).findViewById(R.id.video_item)).setTextColor(Color.parseColor("#003dd5"));} else {//未选中显示黑色
//                            ((TextView) layout.getChildAt(j)).setTextColor(Color.parseColor("#ffffff"));((TextView) (layout.getChildAt(j)).findViewById(R.id.video_item)).setTextColor(Color.parseColor("#000000"));}}if (clarityPopWindow != null) {clarityPopWindow.dismiss();}}};for (int j = 0; j < urlMap.size()+1; j++) {//设置普通的清晰度itemif (j < urlMap.size()) {String key = JZUtils.getKeyFromLinkedMap(urlMap, j);
//                  TextView clarityItem = (TextView) View.inflate(getContext(), R.layout.jz_layout_clarity_item, null);//这里发生变化(这里要细心点,不要写错了哈)LinearLayout clarityItemNormal = (LinearLayout) View.inflate(getContext(), R.layout.jz_layout_clarity_item, null);TextView clarityItem = (TextView) (clarityItemNormal.findViewById(R.id.video_item));clarityItem.setText(key);clarityItemNormal.setTag(j);layout.addView(clarityItemNormal, j);//点击具体某条清晰度tv的点击事件的监听clarityItemNormal.setOnClickListener(mQualityListener);if (j == currentUrlMapIndex) {
//                    clarityItem.setTextColor(Color.parseColor("#fff85959"));clarityItem.setTextColor(Color.parseColor("#003dd5"));}//设置cancel 的 item}else if(j==urlMap.size()) {LinearLayout clarityItemCancel = (LinearLayout) View.inflate(getContext(), R.layout.cancel_jc_layout_clarity_item, null);((TextView)(clarityItemCancel.findViewById(R.id.video_item))).setText("Cancel");
//                    clarityItem.setText("Cancel");layout.addView(clarityItemCancel, j);//点击具体某条清晰度tv的点击事件的监听clarityItemCancel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (clarityPopWindow != null) {clarityPopWindow.dismiss();}}});}}//            clarityPopWindow = new PopupWindow(layout, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);clarityPopWindow = new PopupWindow(layout, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);clarityPopWindow.setContentView(layout);
//            clarityPopWindow.showAsDropDown(clarity);layout.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);//原始的popupwindow的显示位置
//            clarityPopWindow.update(clarity, -40, 46, Math.round(layout.getMeasuredWidth() * 2), layout.getMeasuredHeight());//重新设置使得popupwindow从底部弹出int fullscreenButtonHeight=fullscreenButton.getMeasuredHeight();int[] location = new int[2];v.getLocationOnScreen(location);clarityPopWindow.showAtLocation(bottomProgressBar, Gravity.BOTTOM,location[0]-Math.round(layout_bottom.getMeasuredWidth()),0);//注:layout_bottom在jz_layout_standard中已经有了// android:id="@+id/layout_bottom",这里我们再把它初始化一下,目的是为了是popupwindow可以从底部开始显示}

这时你会发现,popupwindow在很短的时间内就自动消失了,体验不太好
所以,我们还要更改一下,让一段时间内他不自动消失。
仍然在JZVideoPlayerStandard类中
找到DismissControlViewTimerTask的dissmissControlView()方法,注释掉popupwindow的相关代码即可:

public class DismissControlViewTimerTask extends TimerTask {@Overridepublic void run() {dissmissControlView();}
}public void dissmissControlView() {if (currentState != CURRENT_STATE_NORMAL&& currentState != CURRENT_STATE_ERROR&& currentState != CURRENT_STATE_AUTO_COMPLETE) {if (getContext() != null && getContext() instanceof Activity) {((Activity) getContext()).runOnUiThread(new Runnable() {@Overridepublic void run() {bottomContainer.setVisibility(View.INVISIBLE);topContainer.setVisibility(View.INVISIBLE);startButton.setVisibility(View.INVISIBLE);//不让清晰度的popupWindow自动消失,所以此代码注释掉
//                        if (clarityPopWindow != null) {
//                            clarityPopWindow.dismiss();
//                        }if (currentScreen != SCREEN_WINDOW_TINY) {bottomProgressBar.setVisibility(View.VISIBLE);}}});}}
}

还要注意一点,播放完成时,要保证popupwindow是消失的

 @Override
public void onStateAutoComplete() {super.onStateAutoComplete();changeUiToComplete();cancelDismissControlViewTimer();//保证自动播放结束时,popupwindow是消失的if(clarityPopWindow!=null) {clarityPopWindow.dismiss();}bottomProgressBar.setProgress(100);
} 

好了,现在的清晰度切换就基本满足我的要求了,如果你还要其他的显示效果,也照着修改相应的地方即可。
让我们再看下修改后的效果:

3.3 直播流清晰度切换时,出现灰色闪屏问题的解决
直播流如果也有清晰度切换的需求,如果直接使用以上方法, 你会发现在切换清晰度时,会有灰色闪屏现象出现。 这是由于直播流没有总时长和切换时时长记录一说, 而饺子播放器默认在切换清晰度时,会先记录切换清晰度时的进度, 然后新的清晰度会在这个进度的基础上继续进行播放, 直播流是没有记录当前进度,以及从某个进度接着播放之说的, 所以在切换时就会出现灰色闪屏。
要解决这个问题我们只要对onStatePreparingChangingUrl()做相应修改即可, 让其切换清晰度时每次都从0开始,就不会出现灰色闪屏了。

四.沉浸式状态栏

现在的app基本上都要设置沉浸式状态栏,沉浸式状态栏的设置并不困难,但是你会发现设置了沉浸式状态栏后,在播放器进入全屏时,就会变成这个样子了:

下面我们还是一步一步来:
4.1 沉浸式状态的简单集成
这里给大家推荐一个比较好用的设置沉浸式状态栏的第三方库ImmersionBar:
github地址:https://github.com/gyf-dev/ImmersionBar

设置一个粉红色的少女粉作为我们的主题吧
①来到我们的colors.xml文件,稍作修改

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--<color name="colorPrimary">#3F51B5</color>-->
<!--<color name="colorPrimaryDark">#303F9F</color>-->
<color name="colorPrimary">#FFAEB9</color>
<color name="colorPrimaryDark">#FFAEB9</color>
<color name="colorAccent">#FF4081</color><color name="girlColor">#FFAEB9</color></resources>

各个色对应的是那个部位呢,给大家一张图大家就知道了:

②使用第三方库设置沉浸式状态栏:
在Activity的onCreate()中添加如下代码:

 //设置沉浸式状态栏---这里把状态栏和导航栏都设置为纷纷地少女粉mImmersionBar = ImmersionBar.with(this);mImmersionBar.statusBarColor(R.color.girlColor)     //状态栏颜色,不写默认透明色.init();

在Acivity的onDestroy()中:

@Override
protected void onDestroy() {super.onDestroy();if (mImmersionBar != null)mImmersionBar.destroy();  //必须调用该方法,防止内存泄漏,不调用该方法,如果界面bar发生改变,在不关闭app的情况下,退出此界面再进入将记忆最后一次bar改变的状态
}

好了沉浸式状态栏设置结束了

却发现状态栏和布局重叠了~

4.2 状态栏与布局重叠问题的解决
其实只要在布局文件中加一个属性就可以了:

android:fitsSystemWindows="true"

看下效果:

布局重叠确实解决了

4.3 全屏播放视频时,沉浸式状态栏的问题解决
问题是这样的: 播放器全屏时,状态栏仍然执迷不悟的显示,真的很难看。

这里我做的处理是,写一个接口,用来监听播放器进入全屏和退出全屏。

 //为了解决状态栏问题,设置的进入全屏和退出全屏的监听
public void setFullScreenChangedListener(FullScreenChangedListener fullScreenChangedListener){this.mFullScreenChangedListener=fullScreenChangedListener;
}public interface FullScreenChangedListener{void enterFullScreen();void quitFullScreen();}

在进入全屏和退出全屏的地方调用接口的相关方法:

public void startWindowFullscreen() {Log.i(TAG, "startWindowFullscreen " + " [" + this.hashCode() + "] ");hideSupportActionBar(getContext());JZUtils.setRequestedOrientation(getContext(), FULLSCREEN_ORIENTATION);ViewGroup vp = (ViewGroup) (JZUtils.scanForActivity(getContext()))//.getWindow().getDecorView();.findViewById(Window.ID_ANDROID_CONTENT);View old = vp.findViewById(R.id.jz_fullscreen_id);if (old != null) {vp.removeView(old);}textureViewContainer.removeView(JZMediaManager.textureView);try {//在这里会进入全屏状态:if(mFullScreenChangedListener!=null) {mFullScreenChangedListener.enterFullScreen();}Constructor<JZVideoPlayer> constructor = (Constructor<JZVideoPlayer>) JZVideoPlayer.this.getClass().getConstructor(Context.class);JZVideoPlayer jzVideoPlayer = constructor.newInstance(getContext());jzVideoPlayer.setId(R.id.jz_fullscreen_id);FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);vp.addView(jzVideoPlayer, lp);jzVideoPlayer.setUp(urlMap, currentUrlMapIndex, JZVideoPlayerStandard.SCREEN_WINDOW_FULLSCREEN, objects);jzVideoPlayer.setState(currentState);jzVideoPlayer.addTextureView();JZVideoPlayerManager.setSecondFloor(jzVideoPlayer);
//            final Animation ra = AnimationUtils.loadAnimation(getContext(), R.anim.start_fullscreen);
//            jzVideoPlayer.setAnimation(ra);onStateNormal();jzVideoPlayer.progressBar.setSecondaryProgress(progressBar.getSecondaryProgress());jzVideoPlayer.startProgressTimer();CLICK_QUIT_FULLSCREEN_TIME = System.currentTimeMillis();} catch (Exception e) {e.printStackTrace();}
}
 public static boolean backPress() {Log.i(TAG, "backPress");if ((System.currentTimeMillis() - CLICK_QUIT_FULLSCREEN_TIME) < FULL_SCREEN_NORMAL_DELAY)return false;if (JZVideoPlayerManager.getSecondFloor() != null) {CLICK_QUIT_FULLSCREEN_TIME = System.currentTimeMillis();if (JZVideoPlayerManager.getFirstFloor().getCurrentUrl().equals(JZMediaManager.CURRENT_PLAYING_URL)) {JZVideoPlayer jzVideoPlayer = JZVideoPlayerManager.getSecondFloor();jzVideoPlayer.onEvent(jzVideoPlayer.currentScreen == JZVideoPlayerStandard.SCREEN_WINDOW_FULLSCREEN ?JZUserAction.ON_QUIT_FULLSCREEN :JZUserAction.ON_QUIT_TINYSCREEN);JZVideoPlayerManager.getFirstFloor().playOnThisJzvd();} else {//直接退出全屏和小窗JZVideoPlayerManager.getCurrentJzvd().currentState = CURRENT_STATE_NORMAL;JZVideoPlayerManager.getFirstFloor().clearFloatScreen();JZMediaManager.instance().releaseMediaPlayer();JZVideoPlayerManager.setFirstFloor(null);}//return true时会退出全屏if(mFullScreenChangedListener!=null) {mFullScreenChangedListener.quitFullScreen();}return true;} else if (JZVideoPlayerManager.getFirstFloor() != null &&(JZVideoPlayerManager.getFirstFloor().currentScreen == SCREEN_WINDOW_FULLSCREEN ||JZVideoPlayerManager.getFirstFloor().currentScreen == SCREEN_WINDOW_TINY)) {//以前我总想把这两个判断写到一起,这分明是两个独立是逻辑CLICK_QUIT_FULLSCREEN_TIME = System.currentTimeMillis();//直接退出全屏和小窗JZVideoPlayerManager.getCurrentJzvd().currentState = CURRENT_STATE_NORMAL;JZVideoPlayerManager.getFirstFloor().clearFloatScreen();JZMediaManager.instance().releaseMediaPlayer();JZVideoPlayerManager.setFirstFloor(null);//return true时会退出全屏if(mFullScreenChangedListener!=null) {mFullScreenChangedListener.quitFullScreen();}return true;}return false;
}

然后我们再在Activity中取实现这个接口:

public class MainActivity extends AppCompatActivity implements JZVideoPlayer.FullScreenChangedListener {
 lsyVideoPlayer.setFullScreenChangedListener(this);

实现接口的相关方法:

在其进入全屏时,设置状态栏的颜色为透明。
在其退出全屏时,恢复设置状态栏的颜色为少女粉。

/*** 进入全屏时的回调*/
@Override
public void enterFullScreen() {//将状态栏设置为透明mImmersionBar.statusBarColor(R.color.transparent).init();
}/*** 退出全屏时的回调*/
@Override
public void quitFullScreen() {//恢复少女粉mImmersionBar.statusBarColor(R.color.girlColor)    .init();
}

这是我们发现播放器横屏时的状态栏问题就解决了。

4.4 华为5.0虚拟导航栏引起的问题处理
满心欢喜,本以为全屏时导航栏问题解决了,可是拿了个华为5.0的手机一测,又出问题了,问题如下图所示,下面会出一大截黑色条:

从github的issue上找到了相似的问题,看到评论中的方法,试了一下管用!


加上这两句问题就解决了。

.keyboardEnable(true)
.navigationBarWithKitkatEnable(false)

代码下载】:节操播放器在Activity中的使用代码

好了,节操播放器在activity中的使用就先记录到这里,

下次我们说节操播放器在fragment中使用时遇到的各种问题~

积累点滴,做好自己~

节操播放器问题的较完整总结(上)相关推荐

  1. android节操播放器回调,节操播放器(简单使用)

    1. 倒依赖,添加网络权限 implementation 'cn.jzvd:jiaozivideoplayer:6.0.0' 2.添加布局 android:id="@+id/videopla ...

  2. 简单使用github上的节操播放器

    节操播放器又名饺子播放器,那么该如何从github上集成到自己的项目中呢?有两种方法: 1.直接下载开发库地址 https://github.com/lipangit/JieCaoVideoPlaye ...

  3. 2021最新哔哩bilibili视频弹幕播放器带后台版本完整无错修复

    源码介绍: 此款播放器源码添加及修复了很多功能,且所有源码均本地化,不存在外链的情况.站长亲测_测试环境:PHP7.0+MySQL5.6 优化修复功能:1.修复优化播放器播放结束自动下一集代码2.修复 ...

  4. 从节操播放器的基本使用--来体会github的重要性

    转载请注明出处:From李诗雨--http://blog.csdn.net/cjm2484836553/article/details/69927169 不诗意的女程序猿不是好厨师~ 最近一段时间越发 ...

  5. 节操播放器——视频充满布局、监听播放结束(循环播放)、隐藏进度条等

    1.导包:目前测了几个版本的,下面这个版本可以实现充满布局. implementation 'cn.jzvd:jiaozivideoplayer:6.2.4' 2.XML部分: <cn.jzvd ...

  6. Java音乐播放器,窗体程序 完整源码

    今天为大家分享一个音乐播放器的开发与制作,目前系统已经完成了初步功能,后续会进一步完善.整个系统界面漂亮,有完整得源码,希望大家可以喜欢.喜欢的帮忙点赞和关注.一起编程.一起进步 开发环境 开发语言为 ...

  7. android节操播放器回调,Android中节操播放器JieCaoVideoPlayer使用

    ##效果 ##使用 即便是自定义UI,或者对Library有过修改,也是这五步骤来使用播放器. ####1.添加类库 compile 'cn.jzvd:jiaozivideoplayer:6.0.0' ...

  8. 新哔哩bilibili视频弹幕播放器/带后台版本/完整无错

    介绍: 此款播放器源码添加及修复了很多功能,且所有源码均本地化,不存在外链的情况. 测试环境:PHP7.0+MySQL5.6 优化修复功能: 1.修复优化播放器播放结束自动下一集代码 2.修复弹幕后台 ...

  9. android播放器可点击列表,Android上是否有任何播放器可以支持播放列表中的本地视频并可以预设播放顺序?...

    试用Android QQ视频和Vplayer,它确实支持许多视频格式,但是发现它们不支持列表播放. 例如,当前手机上有5个视频剪辑,希望在播放器中设置不同的顺序以顺序播放. 就ABCDE而言,我可以尝 ...

最新文章

  1. perl:cpanm安装方式的一种取代方法
  2. 抽取文档主题之gensim实现
  3. 替代TabActivity,底部菜单主框架搭建
  4. mysql临时文件和临时表_理解mysql的临时表和文件排序
  5. JS转字符 判断数字等
  6. Linux workqueue工作原理 【转】
  7. cpri带宽不足的解决方法_u盘容量不足怎么办 u盘容量不足解决方法【介绍】
  8. 实现机器学习的循序渐进指南I——KNN
  9. 智力问答 48倒计时
  10. Crypto.com APP上线The Graph(GRT)
  11. PostgreSQL的pg_hba.conf文件讲解
  12. web api 安装包
  13. WINDOWS CMAKE与NMAKE
  14. CASS 快捷键设置方法
  15. 电商后台权限设置有哪些规范你知道吗?
  16. STM32F103C8T6红外遥控解码
  17. Java基础篇--设计模式
  18. HZNUOJ 2977 宝可梦决战 种族并查集
  19. jquery获取第一个子元素
  20. QMI8658 - 姿态传感器学习笔记 - Ⅲ

热门文章

  1. 北京大学计算机考博英语,北京大学考博英语总结的经验提供参考
  2. UVE开发环境搭建及项目启动
  3. 编译出错 ninja: build stopped: subcommand failed Android
  4. 因为我是科研废物所以每天翘课摸鱼准备去打工这件事
  5. ppp-GNSS与IGS产品概述
  6. 如何使用 PHP 实现网页交互
  7. 测试=====微信发红包
  8. 29道Zookeeper面试题超详细(附答案)
  9. 数据分析笔记 七种基础数据分析思维方法
  10. Hbuilder X 前端获取后端数据