节操播放器问题的较完整总结(上)
来源:互联网 发布:js编辑器 编辑:程序博客网 时间:2024/05/01 00:34
转载请注明出处:【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.JZVideoPlayerStandard android:id="@+id/lsy_video_player" android:layout_width="match_parent" android:layout_height="200dp"/>
3.Acitivity中:
@Overridepublic void onBackPressed() { if (JZVideoPlayer.backPress()) { return; } super.onBackPressed();}@Overrideprotected 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()方法中:
@Overrideprotected void onResume() { super.onResume(); //播放器重力感应 Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(sensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);}
③然后在onPause()方法中要注意解注册:
@Overrideprotected 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 fullscreen backPress(); 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 { @Override public 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 range while (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"><TextView android: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的颜色--><View android: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"><View android:background="#00000000" android:layout_width="match_parent" android:layout_height="4dp"/><TextViewandroid: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++) { //设置普通的清晰度item if (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() { @Override public 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 { @Override public 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() { @Override public 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是消失的
@Overridepublic 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()中:
@Overrideprotected 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);
实现接口的相关方法:
在其进入全屏时,设置状态栏的颜色为透明。
在其退出全屏时,恢复设置状态栏的颜色为少女粉。
/** * 进入全屏时的回调 */@Overridepublic void enterFullScreen() { //将状态栏设置为透明 mImmersionBar .statusBarColor(R.color.transparent) .init();}/** * 退出全屏时的回调 */@Overridepublic void quitFullScreen() { //恢复少女粉 mImmersionBar .statusBarColor(R.color.girlColor) .init();}
这是我们发现播放器横屏时的状态栏问题就解决了。
4.4 华为5.0虚拟导航栏引起的问题处理
满心欢喜,本以为全屏时导航栏问题解决了,可是拿了个华为5.0的手机一测,又出问题了,问题如下图所示,下面会出一大截黑色条:
从github的issue上找到了相似的问题,看到评论中的方法,试了一下管用!
加上这两句问题就解决了。
.keyboardEnable(true).navigationBarWithKitkatEnable(false)
【代码下载】:节操播放器在Activity中的使用代码
好了,节操播放器在activity中的使用就先记录到这里,
下次我们说节操播放器在fragment中使用时遇到的各种问题~
积累点滴,做好自己~
- 节操播放器问题的较完整总结(上)
- 一个较完整的关键字过滤解决方案(上)
- Android NDK 较完整的总结
- Android NDK 较完整的总结
- 简单的节操视屏播放
- Android 节操视频播放器jiecaovideoplayer使用
- Android 节操视频播放器jiecaovideoplayer使用
- Android中节操播放器JieCaoVideoPlayer使用
- Android中节操播放器JieCaoVideoPlayer使用
- Android 节操视频播放器jiecaovideoplayer使用
- 从节操播放器的基本使用--来体会github的重要性
- Android 仿今日头条视频播放器实现(不使用节操哟)
- JZVIdeoPlayer(节操视频播放)
- 一个较完整的关键字过滤解决方案(中)
- 一个较完整的关键字过滤解决方案(下)
- django实战(二)一个较完整的博客系统
- 较完整的串口类(WINAPI/C++/源码),解决10以上端口,合理结束线程等问题
- 较完整的串口类(WINAPI/C++/源码),解决10以上端口,合理结束线程等问题
- JAVA学习笔记3--类,对象,变量,方法,构造方法,this,引用类型
- Meterpreter常用命令介绍
- python之字符串格式化(format)
- 迅雷创始人程浩:人工智能创业的6大核心问题
- 线性表性质与操作
- 节操播放器问题的较完整总结(上)
- OkHttp3之缓存应用
- x-requested-with 请求头 区分ajax请求还是普通请求
- 自定义View
- Java 8 新特性:Java 类库的新特性之日期时间API (Date/Time API )
- 如何使用pull request
- Acm5-树的基本了解
- Sping Boot+Maven实现多环境切换
- RHCSA测试题