手机影音第六天 自定义播放器页面的实现(按钮暂时未监听)

目前进度的项目源代码托管在里码云上,地址如下:

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>
时间: 2024-10-10 06:08:53

手机影音第六天 自定义播放器页面的实现(按钮暂时未监听)的相关文章

手机影音9--视频播放器的高级功能(2)

1.监听播放出错 class MyOnErrorListener implements MediaPlayer.OnErrorListener { @Override public boolean onError(MediaPlayer mp, int what, int extra) { // Toast.makeText(SystemVideoPlayer.this, "播放出错了哦", Toast.LENGTH_SHORT).show(); //1.播放的视频格式不支持--跳转到

手机影音6--视频播放器的基本功能(3)

1.自定义VideoView 1_自定义VideoView-增加设置视频大小方法 public class VideoView extends android.widget.VideoView { /** * Android系统在更加xml布局找这个类,并且实例化的时候,用该构造方法实例化 * * @param context * @param attrs */ public VideoView(Context context, AttributeSet attrs) { super(conte

手机影音8--视频播放器的高级功能(1)

1.让其他软件能调起自己写的播放器 1.在功能清单文件添加下面的意图 <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.catego

手机影音4--视频播放器的基本功能

1.MediaPlayer和VideoView介绍 Android 系统中提供开发者开发多媒体应用(音视频方面) 一,MediaPlayer, 解码的是底层,MediaPlayer负责和底层打交道,封装了很多方法 start,pause,stop ,播放视频的类 这个MediaPlayer可以播放本地 和网络 的音视频 播放网络资源的时候,要联网权限 1,执行流程 2.视频支持的格式 mp4,3gp,.m3u8 直接用pc的.mp4文件 二,VideoView 显示视频,继承SurfaceVie

手机影音7--视频播放器的基本功能(4)

1.用AudioManager调声音 1_得到当前音量和最大音量 //关于设置音量 private int currentVolume;//当前音量值 private int currentMaxVolume;//当前最大音量 private AudioManager am; am = (AudioManager) getSystemService(AUDIO_SERVICE); currentVolume = am.getStreamVolume(AudioManager.STREAM_MUS

基于 AVPlayer 自定义播放器

如果我只是简单的播放一个视频,而不需要考虑播放器的界面.iOS9.0 之前使用 MPMoviePlayerController, 或者内部自带一个 view 的 MPMoviePlayerViewController.  iOS9.0 之后,可以使用 AVPictureInPictureController, AVPlayerViewController, 或者 WKWebView. 以上系统提供的播放器由于高度的封装性, 使得自定义播放器变的很难. 所以,如果我需要自定义播放器样式的时候,可以

使用html5中video自定义播放器必备知识点总结以及JS全屏API介绍

一.video的js知识点: controls(控制器).autoplay(自动播放).loop(循环)==video默认的: 自定义播放器中一些JS中提供的方法和属性的记录: 1.play()控制视频的播放 2.pause()控制视频的停止 3.currentTime控制视频的当前时间 4.muted控制视频是否静音(赋值true or false) 5.volume控制音量的大小(赋值0-1) 6.duration视频的总时间 7.ontimeupdate事件(当前播放位置改变时执行,使用时

拖拽和自定义播放器

今天用到了拖拽,这个是在h5中的,拖拽其实拖得是标签,把标签当做一个全局变量,你想拖到哪儿就拖到哪儿,我们知道的标签中的img是默认支持拖拽的,所以不要设置属性,但其他的就要设置一个属性才能实现拖拽: 必须要有draggable=true才能实现. 拖拽一般是结合js使用的,光听意思就知道拖拽是动作了,它有几个注册事件: 1:开始拖拽时,是开始拖拽是的状态: 2:有开始就有结束: 他们两个其实很好记,就一个单词不一样,一个是start一个end,他们本身的意思就是一个开始一个结束的意思. 一般标

h5自定义播放器得实现原理

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <!--插入播放按钮得文字图标格式(具体使用方法可以百度http://fontawesome.dashgame.com/)--> 7 <link rel="stylesheet&