目前进度的项目源代码托管在里码云上,地址如下:
https://git.oschina.net/joy_yuan/MobilePlayer
感兴趣的可以去下载看看,多多支持
这次就摒弃了系统自带的控制栏,即之前写的通过系统自带的控制栏
videoview.setMediaController(new MediaController(this));
转而自己写控制器布局,实际截图如下:
效果图:
一、Activity的声明周期重温与横竖屏切换时的问题
有2个页面,A页面,B页面,下面括号里的A,B代表是哪个页面的声明周期方法,不是参数
1、 当从A页面,切换到B页面时,B页面全覆盖A页面
1.1、那么2个Activity的声明周期变化,如下:
onCreate (A) --->onStart (A) ----->onResume(A)------>onPaused(A)------>onCreate(B)---
-->onStart(B)---->onResume(B)----onStop(A)
1.2、按回退键从B回到A时,变化如下
onPause(B)---->onRestart(A)--->onStart(A)---->onResume(A)--->onStop(B)--
-->onDestroy(B)
2、当从A切换到B时,B页面类似弹框,没有覆盖全A,那么声明周期变化如下
2.1、onCreate(A)--->onStart(A)---->onResume(A)----->onPaused(A)---->onCreate(B)---->onStart(B)---->onResume(B) 因为A没有被全部覆盖,所以A没有停
2.2按回退键,退回到A时
onPaused(B)---->onResume(A)---->onStop(B)---->onDestroy(B)
---------------------------------------------------------------------------------------------------
对于之前写的代码,如果进入到了主页面,即显示视频列表的页面后,有一个小Bug,即切换横竖屏,会导致程序崩溃,原因在与切换横竖屏后,,系统会自动的重新去create 一个MainActivity,这时候就有2个MainActivity,导致崩溃。解决办法是在AndroidManifext.xml里注册activity时,设置忽略几个屏幕变化的监听,代码如下:
即多了 android:configChanges="keybordHidden|screenSize|orientation"
<activity android:name=".activity.SplashActivity" android:configChanges="keyboardHidden|screenSize|orientation" > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>
同时对于之前的播放器,如果在播放视频时,切换横竖屏时,会导致视频从新播放,解决办法同样是在播放器的这个activity里加入上面的配置。完整的AndroidManifext.xml如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yuanlp.mobileplayer"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".activity.SplashActivity" android:configChanges="keyboardHidden|screenSize|orientation" > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".activity.MainActivity" android:launchMode="singleTask"> </activity> <activity android:name=".activity.SystemVideoPlayer" android:configChanges="keyboardHidden|screenSize|orientation" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" ></activity> </application> </manifest>
二、分析布局
实际效果没有横屏最上方的系统自己的状态栏,只是利用手机截图时把状态栏拉下来了
1、整体布局是一个RelativeLayout,这样就可以用top和bottom来控制声音控制栏和进度控制栏的布局
2、子布局使用LinearLayout的好处之一是,可以使用weight权重这个属性,这样就可以方便的实现根据权重来平均分割宽度,如最下方的那几个暂停、上一个,下一个等5个按钮,就是设置button的weight为1.
3、声音控制栏上面其实还有一栏,只是被覆盖了,是一个Linearlayout,和声音控制栏一样,其中声音的进度条SeekBar的权重是1,其余的声音图标和右边的i图标就会自动被挤开。
4、下方的播放进度条和5个按钮,放在一个LinearLayout中,这个布局根据RelativeLayout放在底部,并且是一个vertical布局,其中有2个LinearLayou子布局,2个子布局都是水平布局。
三、布局代码
1、system_video_player.xml
与昨天相比,就include一个自定义的布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:gravity="center" android:background="#000000" android:layout_width="match_parent" android:layout_height="match_parent"> <VideoView android:layout_centerInParent="true" android:id="@+id/videoview" android:layout_width="match_parent" android:layout_height="match_parent"/> <include layout="@layout/media_controller"/> </RelativeLayout>
2、media_controller.xml 自定义的各种控制按钮的布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_top" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:gravity="center_vertical" android:background="@drawable/bg_player_status" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_weight="1" android:id="@+id/tv_name" android:layout_marginLeft="8dp" android:text="视频的名称" android:textColor="#ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id="@+id/iv_battery" android:layout_marginRight="8dp" android:src="@drawable/ic_battery_0" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/tv_system_time" android:layout_marginRight="8dp" android:textColor="#ffffff" android:text="12:00" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:gravity="center_vertical" android:background="@drawable/bg_player_top_control" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/btn_voice" android:background="@drawable/btn_voice_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <SeekBar android:id="@+id/seekbar_voice" android:progress="20" android:progressDrawable="@drawable/progress_horizontal" android:thumb="@drawable/progress_thumb" android:minHeight="6dp" android:maxHeight="6dp" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/switch_player" android:background="@drawable/btn_switch_player_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout> <LinearLayout android:layout_alignParentBottom="true" android:id="@+id/ll_bottom" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:background="@drawable/bg_player_bottom_seekbar" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:text="0:00" android:textColor="#ffffff" android:id="@+id/tv_current_time" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <SeekBar android:id="@+id/seekbar_video" android:progress="20" android:progressDrawable="@drawable/progress_horizontal" android:thumb="@drawable/progress_thumb" android:minHeight="6dp" android:maxHeight="6dp" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:text="20:00" android:textColor="#ffffff" android:id="@+id/tv_duration" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:gravity="center_vertical" android:background="@drawable/bg_player_bottom_control" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:layout_weight="1" android:id="@+id/bt_exit" android:background="@drawable/bt_exit_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:layout_weight="1" android:id="@+id/bt_video_pre" android:background="@drawable/bt_video_pre_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:layout_weight="1" android:id="@+id/bt_video_start_pause" android:background="@drawable/bt_video_pause_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:layout_weight="1" android:id="@+id/bt_next" android:background="@drawable/bt_next_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:layout_weight="1" android:id="@+id/bt_video_switch_screen" android:background="@drawable/bt_video_switch_screen_full_selector" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout> </RelativeLayout>