温馨提示:
功能比较多且文章也比较长,可在左边菜单栏打开目录按标题查找;
或者按CTRL+F即网页按关键字查找,输入自己需要功能关键字就能跳转到目的地了。
先说明一下,本人大二,就读于一所普通的不能再普通的二本,Android是自学,这个项目自己前前后后花了比较久的时间,因为边学边做,也是磕磕绊绊的过来了,80%原创,20%是邵发的安卓入门视频(http://www.afanihao.cn/java.jsp)最后一个专题视频播放器带进来的,看视频纯手写代码,但是发哥的视频播放器项目只有简单的功能:利用VideoView打开本地视频,SeekBar滑动进度条,暂停/播放按钮就没了,自己还是感谢发哥把我带入安卓(之前从Java Web跳到Android)。
写这篇博客主要有几点原因,一是想把自己这段时间内容总结一下,二是跟大家互相讨论,看有什么可以优化。第一次写CSDN博客,有什么不足之处请谅解,毕节本人还是个大二的宝宝啊,是不是(嘿嘿嘿)?
项目原创!文章原创!所以转载请注明出处!
本人第一次写视频播放器项目,自己觉得有许多很多可以优化的地方,有什么不足的不够完美不够好的,欢迎大家举出来,一起讨论。
有个不知道算不算bug的bug,就是项目安卓到手机上,提示安装时显示的是我的创建项目的名字:Mydemo1101,但是安装完App名字是我设置好的App名字,估计有解决办法,目前只是学习测试用,不管了。
我用的是Android Studio 2.3.3 版本,写的博客教程代码只是截取代码,一些东西比较杂就没贴,太麻烦了,所以博客可以看到我的思路我的想法,如果想要完整项目可以在我的CSDN资源下载,我上传到CSDN了,项目下载地址贴上:
https://download.csdn.net/download/drogon1999/10393876
首先先说一下我的项目有什么功能:
1、发哥Android入门视频的 打开本地媒体器,SeekBar滑动进度条,暂停/播放按钮三个功能;
以下功能是自己完善添加的:
2、锁定按钮功能;
3、分享功能(两种机制 如果是本地视频则分享视频,如果是网络视频分享网络视频地址);
4、VideoView滑动监听(快进快退,音量加减、亮度加减);
5、全屏按钮和缩小按钮点击功能;
6、右上角显示当前时间,上面中间显示视频当前进度,左上角显示标题(本地视频显示标题,网络视频显示地址);
7、播放网络视频功能;
8、单击双击监听(双击暂停,单击显示所有状态)
9、按返回键,连续按两次才会退出,按一次提醒再按一次才会退出
10、视频播放器能够出现在打开方式上,即视频长按可以选择我的播放器进行播放
11、所有显示的东西三秒后自动隐藏
首先说一下布局文件,从发哥学到了横屏竖屏可以专门用两个xml文件分别对应竖屏和和横屏的界面,我就采用了两个xml文件。并且图标是从阿里巴巴矢量图标库下载,APP应用的图片是从百度文库下载的(好像部分图片有版权问题,但我只是学习用会不会被查水表???顶多赚点C币,应该不会吧(萌新瑟瑟发抖))。
先看预览图,我考虑了用户不清楚每个按钮的作用,在最开始显示了类似于说明的图片,点击任意地方都能隐藏,当然竖屏横屏显示的说明的图片是不一样的,但是功能是一样的,缺点是每次打开都会显示。。。(是不是可以把说明改成广告???嘿嘿嘿我真是个天才)
说明图片(横屏竖屏的说明图片只是里面内容位置不一样,就放一张横屏的了,但是我的项目好像设置了切换屏幕时将这个说明书关闭???大概可估计能你们只能看到竖屏的说明书,横屏你们就别想看了(这应该不重要,对,不重要)):
布局界面代码:
用了FrameLayout控件,个人看来好处是可以分层,优点是互不影响,缺点还是互不影响,可能对界面设计不精通,分层的控件不知道怎么相互联系。
一个水平Layout的标题栏,里面放了三个子控件(横屏左边视频标题,中间视频当前位置和总时间(类似于01:34/05:04),右边显示时间,),竖屏就两个子控件没有右边的显示当前时间。并且标题TextView设置了单行显示,8个字数限制,超过用省略号替代(在xml布局有注释);
一个VideoView空间播放视频;
一个水平Layout的网络视频栏,这个是输入网络视频地址和跳转;(默认属性是GONE隐藏的,只有点击网络视频按钮才会显示)
一个主工具栏,从左边开始全屏/缩小按钮,打开本地视频资源按钮,打开网络视频栏按钮,播放/暂停按钮,最后是进度条。
一个缓存加载的动态图,用于显示加载网络视频的缓存过程,不过Android Studio没有自带播放动态图的空间,用了第三方的控件(包名为android-gif_drawable-1.2.9.aar),如何加入第三方呢,简单说一下,将AAR包复制到项目的\app\libs文件夹下面,然后在build.gradle(Module:app)加入一些代码(如图):注意三个红框是否相同,修改guild文件记得点击右上角的Sync Now进行全局更新配置文件,这样就会Android Studio会自动加载libs文件夹下的android-gif_drawable-1.2.9.aar包,然后用法手动在Text手动添加第三方包,代码在下面xml布局文件里。
需要的权限:
先在mainifests/AndroidManifest.xml 写上需要的权限代码,并且更改主题为没有自带标题栏的主题,还有拦截VideoView视频源只能播放VIdeo/*:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.mydemo1101">
<!-- 权限列表 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="@drawable/im_icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="video/*"/>
</intent-filter>
</activity>
</application>
</manifest>
而没有自带的标题栏需要在values/styles.xml文件添加代码:
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
横屏布局activity_main_landscape:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000"
tools:context="example.mydemo1101.MainActivity">
<VideoView
android:id="@+id/id_videoview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"/>
<ImageView
android:id="@+id/id_help"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/im_help"/>
<LinearLayout
android:id="@+id/id_title_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="top"
android:orientation="horizontal"
android:padding="8dp">
<!-- android:lines="1" // 单行显示
android:maxEms="8" //最多显示8个字
android:ellipsize="end" //剩余的用省略号代替
android:hint="请输入视频地址" // 表示灰色的字体,不用删除点击直接输入会自动消失-->
<TextView
android:id="@+id/id_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="视频标题"
android:gravity="left"
android:lines="1"
android:maxEms="8"
android:ellipsize="end"
android:textColor="#1296db"
android:textSize="24sp"/>
<TextView
android:id="@+id/id_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="00:00/00:00"
android:gravity="center"
android:textColor="#EDA24C"
android:textSize="22sp"/>
<TextView
android:id="@+id/id_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="00:00:00"
android:gravity="right"
android:textColor="#1296db"
android:textSize="24sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_internetvideo_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="top"
android:orientation="horizontal"
android:visibility="gone"
android:padding="8dp"
android:weightSum="1">
<EditText
android:id="@+id/id_internetUri"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#FBD3B5"
android:ems="10"
android:inputType="textPersonName"
android:hint="请输入视频地址"
android:layout_weight="1"
android:textColor="#00A1D6"
android:textSize="24sp"/>
<ImageButton
android:id="@+id/id_internetSure"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#DA5380"
app:srcCompat="@drawable/ic_sure"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_control_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:background="#0fff"
android:orientation="horizontal"
android:padding="4dp"
android:weightSum="1">
<ImageButton
android:id="@+id/id_fullscreen"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:background="#0000"
android:onClick="fullScreen"
app:srcCompat="@drawable/ic_video_less_screen"/>
<ImageButton
android:id="@+id/id_selectFile"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:background="#0000"
android:onClick="openFile"
app:srcCompat="@drawable/ic_media_open"/>
<ImageButton
android:id="@+id/id_internet"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:background="#0000"
app:srcCompat="@drawable/ic_internet"/>
<ImageButton
android:id="@+id/id_play_pause"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#0000"
app:srcCompat="@drawable/ic_play"/>
<SeekBar
android:id="@+id/id_seekbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="4dp"
/>
</LinearLayout>
<pl.droidsonroids.gif.GifImageView
android:id="@+id/id_loading_gif"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="#0000"
android:visibility="gone"
android:src="@drawable/loading"
/>
<TextView
android:id="@+id/id_textview"
android:layout_width="192dp"
android:layout_height="95dp"
android:layout_gravity="center"
android:background="#0000"
android:gravity="center"
android:textColor="#1296db"
android:textSize="28sp"/>
<ImageButton
android:id="@+id/id_locked_unlocked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center"
android:layout_marginLeft="16dp"
android:background="#0000"