学习目标熟练使用RecyclerView显示列表数据
了解MediaPlayer播放原理
熟练使用MediaPlayer播放在线视频
熟悉MediaPlayer常见的监听
掌握MediaPlayer播放,暂停,重播等功能
能够对SeekBar自定义样式
视频-项目基本结构搭建引言由于市面上大部分app含有在线播放视频的功能。
在列表中,嵌套一些视频,当我们点击播放按钮,就可以在线播放视频。
回顾大家思考一下,如何实现这样的功能呢?
整体的列表我们可以参考使用:recyclerView + adapter
列表每个条目中我们可以使用:
TextView显示视频标题
TextureView + MeidaPlayer来实现视频播放界面
好! 接下来,跟随传智播客一起搭建项目的基本结构框架
项目的分析基本项目的结构包含以下内容:
l RecyclerView + Adapter + Holder
l 控件的初始化ButterKnift
l 联网:权限
l 布局管理器、分割线
l 视频播放界面使用TextureView + MeidaPlayer
实现步骤首先我们初始RecyclerView + adapter将列表显示出来!
第一步:创建MainActivity界面布局在项目的res/layout目录下创建MainActivity布局
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<!--传智播客-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.itheima.videoplayerlist.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
第二步:初始化控件
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity {
//传智播客
@BindView(R.id.rv)
RecyclerView rv;
private List<VideoPlayerItemInfo> videoPlayerItemInfoList;
private LinearLayoutManager lm;
private VideoPlayListAdatper adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//网络视频路径
String url = "http://flv2.bn.netease.com/videolib3/1604/28/fVobI0704/SD/fVobI0704-mobile.mp4";
//数据的初始化
videoPlayerItemInfoList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
videoPlayerItemInfoList.add(new VideoPlayerItemInfo(i,url));
}
//初始化RecyclerView
lm = new LinearLayoutManager(this);
//设置布局管理器
rv.setLayoutManager(lm);
//添加分割线
rv.addItemDecoration(new RecycleViewDivider(this,LinearLayoutManager.HORIZONTAL,1, Color.BLACK));
//创建适配器
adapter = new VideoPlayListAdatper(this, videoPlayerItemInfoList);
//设置适配器
rv.setAdapter(adapter);
}
}
第三步:适配器
[Java] 纯文本查看 复制代码
public class VideoPlayListAdatper extends RecyclerView.Adapter {
//传智播客
private Context context;
private List<VideoPlayerItemInfo> videoPlayerItemInfoList;
public VideoPlayListAdatper(Context context, List<VideoPlayerItemInfo> videoPlayerItemInfoList) {
this.context = context;
this.videoPlayerItemInfoList = videoPlayerItemInfoList;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_video_play, parent, false);
MyViewHolder viewHolder = new MyViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return videoPlayerItemInfoList != null ? videoPlayerItemInfoList.size() : 0;
}
}
第四步:设置适配器
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity {
//传智播客
@BindView(R.id.rv)
RecyclerView rv;
private List<VideoPlayerItemInfo> videoPlayerItemInfoList;
private LinearLayoutManager lm;
private VideoPlayListAdatper adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//网络视频路径
String url = "http://flv2.bn.netease.com/videolib3/1604/28/fVobI0704/SD/fVobI0704-mobile.mp4";
//数据的初始化
videoPlayerItemInfoList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
videoPlayerItemInfoList.add(new VideoPlayerItemInfo(i,url));
}
//初始化RecyclerView
lm = new LinearLayoutManager(this);
//设置布局管理器
rv.setLayoutManager(lm);
//添加分割线
rv.addItemDecoration(new RecycleViewDivider(this,LinearLayoutManager.HORIZONTAL,1, Color.BLACK));
//创建适配器
adapter = new VideoPlayListAdatper(this, videoPlayerItemInfoList);
//设置适配器
rv.setAdapter(adapter);
}
}
视频-条目布局的分析和设计
引言项目的基本结构搭建出来,之后,接下来我们分析一下每个条目的布局设计。
从整个条目来分析:
分为两部分内容:
红色区域为视频播放内容
绿色区域为视频内容
从布局结构来分析:
视频播放界面: ImageView+ 视频播放组件
视频内容:
LinearLayout
ImageView
TextView
等
实现步骤第一步:条目布局分析条目的总布局为:LinearLayout
视频播放布局:FrameLayout
ImageView
自定义控件:MyVideoPlayer
视频内容布局:LinearLayout
2个ImageView
3个TextView
第二步:布局结构第三步:布局代码实现[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<!--传智播客-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#c4c0c0"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<ImageView
android:id="@+id/iv_bg"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="fitXY"
android:src="@drawable/img_0"
android:visibility="visible" />
<com.itheima.videoplayerlist.view.MyVideoPlayer
android:id="@+id/videoPlayer"
android:layout_width="match_parent"
android:layout_height="200dp"
android:visibility="visible"></com.itheima.videoplayerlist.view.MyVideoPlayer>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ece8e8"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/iv_author"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/qq_allshare_normal" />
<TextView
android:id="@+id/tv_author_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="飞行的钢蛋儿"
android:textColor="#000" />
<TextView
android:id="@+id/tv_play_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="109万次播放"
android:textColor="#8b8787" />
<ImageView
android:id="@+id/iv_comment"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="2dp"
android:background="@drawable/comment_video_normal" />
<TextView
android:id="@+id/tv_comment_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="3940"
android:textColor="#8b8787" />
<ImageView
android:id="@+id/iv_comment_more"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/more_pgc_comment_normal_night" />
</LinearLayout>
</LinearLayout>
第四步:视频播放界面的封装从布局代码中,包含一个自定义控件MyVideoPlayer
MyVideoPlayer:用于控制视频的显示和播放,这样方面后期的维护
MyVideoPlayer封装
MyVideoPlayer 继承RelativeLayout布局
初始化布局并初始化控件
[Java] 纯文本查看 复制代码
public class MyVideoPlayer extends RelativeLayout {
private static final String TAG = "MyVideoPlayer";
@BindView(R.id.video_view)
public TextureView videoView;
@BindView(R.id.mediaController)
public MyVideoMediaController mediaController;
public MyVideoPlayer(Context context) {
this(context, null);
}
public MyVideoPlayer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyVideoPlayer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
//初始化布局
private void initView() {
View view = View.inflate(getContext(), R.layout.video_play, this);
ButterKnife.bind(this,view);
}
}
MyVideoPlayer布局的结构
MyVideoPlayer布局包含两部内容:
视频播放界面: TextureView
视频播放控制界面: 自定义控件 – MyVideoMediaController
布局代码实现:
[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="wrap_content">
<!--视频播放界面-->
<TextureView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#f00"
android:visibility="visible"/>
<!--视频播放控制界面-->
<com.itheima.videoplayerlist.view.MyVideoMediaController
android:id="@+id/mediaController"
android:layout_width="match_parent"
android:layout_height="wrap_content"></com.itheima.videoplayerlist.view.MyVideoMediaController>
</RelativeLayout>
MyVideoMediaController布局结构
MyVideoMediaController:用于控制视频播放
比如:暂停,重播,快速播放等操作
MyVideoMediaController继承 RelativeLayout布局
初始化布局和控件
布局代码实现:
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<!--传智播客-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
>
<!--视频加载进度条-->
<ProgressBar
android:id="@+id/pb_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<RelativeLayout
android:id="@+id/rl_play_finish"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:background="#b4000000">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginRight="20dp"
>
<ImageView
android:id="@+id/iv_replay"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/replay_video"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="重播"
android:layout_gravity="center_horizontal"
android:textSize="14sp"
android:textColor="#fff"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<ImageView
android:id="@+id/iv_share"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/share_video"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="分享"
android:layout_gravity="center_horizontal"
android:textSize="14sp"
android:textColor="#fff"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="百年人参下的守护毒蛇,往往是采参人伤亡惨重的最直接原因"
android:textColor="#fff"
android:textSize="14sp"
android:layout_margin="10dp"/>
<ImageView
android:id="@+id/iv_play"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:src="@drawable/new_play_video"
android:visibility="visible" />
<TextView
android:id="@+id/tv_all_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="10dp"
android:textColor="#fff"
android:textSize="10sp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:visibility="visible"
android:background="@drawable/tv_time_bg"
android:text="02:30"/>
<LinearLayout
android:id="@+id/ll_play_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ca000000"
android:layout_gravity="bottom"
android:gravity="center_vertical"
android:visibility="visible"
android:padding="10dp"
>
<TextView
android:id="@+id/tv_use_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:textColor="#fff"
android:text="00:00"
android:layout_marginRight="10dp"/>
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:thumb="@drawable/biz_video_progress_thumb"
android:progressDrawable="@drawable/sb_progress_drawable"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:textColor="#fff"
android:text="02:30"
android:layout_marginRight="10dp"/>
<ImageView
android:id="@+id/iv_fullscreen"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/enlarge_fullscreen"/>
</LinearLayout>
</FrameLayout>