1、9.1 视频播放器 对于一个视频播放器来说,常见的功能有进度条显示和拖动功能,用户对于一个视频播放器来说,常见的功能有进度条显示和拖动功能,用户拖动进度条可以快进和快退,在播放的过程中,进度条应该不断地更新播放拖动进度条可以快进和快退,在播放的过程中,进度条应该不断地更新播放的时间和显示视频总时长,同时还需要提供暂停的时间和显示视频总时长,同时还需要提供暂停/继续播放功能。继续播放功能。9.1.1 9.1.1 界面布局界面布局 界面主体部分需要添加一个界面主体部分需要添加一个 SurfaceView SurfaceView 用于显示播放的内容,然后用于显示播放的内容,然后需要显示进度条和播控按
2、钮。需要显示进度条和播控按钮。为了可以更灵活地布局这些组件,布局方式可以采用为了可以更灵活地布局这些组件,布局方式可以采用 RelativeLayout RelativeLayout。在布局文件中,外层的视图容器为相对布局方式,其中添加了一个在布局文件中,外层的视图容器为相对布局方式,其中添加了一个SurfaceView SurfaceView 视图,视图,layout_widthlayout_width和和 layout_height layout_height 的值都为的值都为 match_parentmatch_parent,使得播放内容占满整个画面。其后定义了一个垂直的线性,使得播放内
3、容占满整个画面。其后定义了一个垂直的线性布局,用于显示进度条和播控按钮等内容,通过设置布局,用于显示进度条和播控按钮等内容,通过设置 android:layout_ android:layout_ alignBottom=id/svewalignBottom=id/svew使得该布局与使得该布局与 SurfaceView SurfaceView 的底部对齐,设置的底部对齐,设置 android:alpha android:alpha 属性让其具有一定的透明度。在该布局中,首先定义了一属性让其具有一定的透明度。在该布局中,首先定义了一个个 SeekBar SeekBar 用于显示播放的进度和拖动
4、条,然后定义了一个水平的线性布用于显示播放的进度和拖动条,然后定义了一个水平的线性布局用于显示播控按钮和播放时间。播控按钮通过设置局用于显示播控按钮和播放时间。播控按钮通过设置 android:clickable=android:clickable=truetrue使得该图片可以被单击,用于实现播放使得该图片可以被单击,用于实现播放/暂停功能。暂停功能。页面具体效果如图页面具体效果如图 9.1 9.1 所示。所示。图 9.1 页面布局9.1.2 9.1.2 初始化初始化 视频播放需要指定视频所在的路径或视频播放需要指定视频所在的路径或 URL URL,本章我们基于第,本章我们基于第 5 5 章
5、小练章小练习的文件浏览器获取视频路径,在文件浏览的过程中,如果是文件夹,则进习的文件浏览器获取视频路径,在文件浏览的过程中,如果是文件夹,则进入下级目录,如果是视频文件,则调用本章的视频播放器,并将视频的路径入下级目录,如果是视频文件,则调用本章的视频播放器,并将视频的路径作为参数传入,其他文件则返回。作为参数传入,其他文件则返回。在组件的初始化函数在组件的初始化函数 initWidget()initWidget()方法中,首先通过方法中,首先通过findViewById()findViewById()方法获取各个控件,然后为进度的显示和进度条的位置设置初始值方法获取各个控件,然后为进度的显示
6、和进度条的位置设置初始值 。通过。通过 setOnClickListenersetOnClickListener方法为播控图片设置监听事件。方法为播控图片设置监听事件。9.1.3 9.1.3 播控和进度控制播控和进度控制 在视频播放中,暂停、继续播放和进度拖动是常见的操作。播控是通过监在视频播放中,暂停、继续播放和进度拖动是常见的操作。播控是通过监听图片的单击事件实现的。听图片的单击事件实现的。在图片按钮被单击后,首先判断当前视频的状态,如果是播放状态,则调在图片按钮被单击后,首先判断当前视频的状态,如果是播放状态,则调用用 MediaPlayer MediaPlayer 类类 的的 paus
7、e()pause()方法暂停播放,同时更换播控的图片,显示播方法暂停播放,同时更换播控的图片,显示播放按钮。如果是暂停状态,则调用放按钮。如果是暂停状态,则调用MediaPlayer MediaPlayer 类的类的 start()start()方法继续播放,方法继续播放,同时更换播控的图片,显示暂停按钮。播放和暂停页面如图同时更换播控的图片,显示暂停按钮。播放和暂停页面如图 9.2 9.2 和图和图 9.3 9.3 所所示。示。图 9.2 播放状态图 9.3 暂停状态 拖动进度条进行快进和快退是通过监听拖动进度条进行快进和快退是通过监听 OnSeekBarChangeListener OnS
8、eekBarChangeListener 事件实现的,首先在代码中通过事件实现的,首先在代码中通过setOnSeekBarChangeListener()setOnSeekBarChangeListener()为拖动条为拖动条设置事件监听,然后重写设置事件监听,然后重写 OnseekBarChangeListener OnseekBarChangeListener 的回调函数,在不的回调函数,在不同的事件触发下执行不同的动作。同的事件触发下执行不同的动作。在在 OnseekBarChangeListener OnseekBarChangeListener 的回调函数中,的回调函数中,onPro
9、gressChanged onProgressChanged 在拖动条发生改变时回调,并回调滑块当前的位置,在其中可以根据滑块的在拖动条发生改变时回调,并回调滑块当前的位置,在其中可以根据滑块的位置计算需要定位的视频位置,然后调用位置计算需要定位的视频位置,然后调用 MediaPlayer MediaPlayer 的的seekTo()seekTo()方法方法跳转到对应的位置。跳转到对应的位置。onStartTrackingTouch onStartTrackingTouch 在拖动条被触摸时回调,其在拖动条被触摸时回调,其中可以调用中可以调用MediaPlayer MediaPlayer 的的
10、 pause()pause()方法暂停视频的播放。方法暂停视频的播放。onStopTrackingTouch onStopTrackingTouch 在拖动条被释放时回调,此时快进或快退已经在拖动条被释放时回调,此时快进或快退已经完成,调用完成,调用 MediaPlayer MediaPlayer 的的 start()start()方法继续播放。方法继续播放。在播放的过程中,需要根据当前视频播放的时间实时更新进度和时间在播放的过程中,需要根据当前视频播放的时间实时更新进度和时间显示的进度,可以通过显示的进度,可以通过Handler Handler 和和 Runnable Runnable 任务
11、实现。任务实现。9.1.4 9.1.4 横屏设置横屏设置 在视频播放中,一般会自动切换到横屏显示,即视频的宽比高大,这在视频播放中,一般会自动切换到横屏显示,即视频的宽比高大,这可以在声明可以在声明 Activity Activity 时通过指定时通过指定 android:screenOrientation android:screenOrientation 属性实属性实现。现。android:screenOrientation android:screenOrientation 属性支持属性支持 3 3 种取值,种取值,landscapelandscape强强制横屏显示,制横屏显示,port
12、raitportrait强制竖屏显示,默认值为强制竖屏显示,默认值为unspecifiedunspecified,显示,显示方向跟随系统屏幕旋转的方向。方向跟随系统屏幕旋转的方向。本章我们分模块介绍了一个视频播放页面的实现,首先介绍了界面的本章我们分模块介绍了一个视频播放页面的实现,首先介绍了界面的布局方式,可以看到相对布局和线性布局在实际开发中的灵活组合和应用。布局方式,可以看到相对布局和线性布局在实际开发中的灵活组合和应用。然后介绍了控件和播放器的初始化,回顾了通过然后介绍了控件和播放器的初始化,回顾了通过 Intent Intent进行数据传递的操进行数据传递的操作。后面通过对播控和进度
13、控制的分析,展示了作。后面通过对播控和进度控制的分析,展示了 Android Android 中基于回调的事中基于回调的事件监听机制和使用件监听机制和使用 Handler Handler 实现在线程中异步刷新实现在线程中异步刷新 UI UI 页面的操作。最后页面的操作。最后通过将通过将 Activity Activity 设置成横屏显示,熟悉了在设置成横屏显示,熟悉了在 AndroidMainfest.xml AndroidMainfest.xml 文文件中对件中对 Activity Activity 进行属性设置的方法。需要指出的是,在进行属性设置的方法。需要指出的是,在 Android Android 的的 xmlxml配置文件中,可以对界面的视图和各个组件做各种属性的设置,本书并配置文件中,可以对界面的视图和各个组件做各种属性的设置,本书并不能一一涵盖,需要各位读者在开发过程中不断进行积累和熟悉。不能一一涵盖,需要各位读者在开发过程中不断进行积累和熟悉。