主布局:
1 29 10 15 16
主布局的Item:
1 26 7 12 13 18 19 24 25 30 31
主界面Activity:
1 /** 2 * 1、封装播放视频的SurfaceView 3 * 2、网络请求数据(手写bean):bean、httpservice 4 * 3、放在RecyclerView中展示 5 * 4、item中放入SurfaceView 6 * 5、点击播放弹出通知 7 * 6、进度 8 */ 9 public class MainActivity extends AppCompatActivity implements Callback{10 11 protected RecyclerView mRecyclerView;12 private Object mData;13 14 @Override15 protected void onCreate(Bundle savedInstanceState) {16 super.onCreate(savedInstanceState);17 super.setContentView(R.layout.activity_main);18 initView();19 20 initData();21 }22 23 private void initData() {24 Retrofit retrofit = new Retrofit.Builder()25 .baseUrl("http://baobab.kaiyanapp.com/")26 .addConverterFactory(GsonConverterFactory.create()).build();27 28 retrofit.create(KaiyanHttpService.class)29 .getKaiyanCall()30 .enqueue(this);31 }32 33 private void initView() {34 mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);35 }36 37 @Override38 public void onResponse(Call call, Response response) {39 KaiyanBean kaiyanBean = response.body();40 41 List videoList = new ArrayList<>();42 43 for (KaiyanBean.ItemBean itemBean : kaiyanBean.getItemList()) {44 Log.d("1507","type: " + itemBean.getType()+ ", title : " + itemBean.getData().getTitle() + "url : " + itemBean.getData().getPlayUrl());45 46 if ("video".equals(itemBean.getType())) {47 // 过滤掉type不为video的数据48 VideoBean videoBean = new VideoBean(itemBean.getData().getTitle(), itemBean.getData().getPlayUrl());49 videoList.add(videoBean);50 }51 52 }53 54 VideoListAdapter adapter = new VideoListAdapter(this, videoList);55 mRecyclerView.setAdapter(adapter);56 }57 58 @Override59 public void onFailure(Call call, Throwable t) {60 61 }62 }
Bean:
1 package net.bwie.surfaceviewvideolist.bean; 2 3 import java.util.List; 4 5 public class KaiyanBean { 6 7 private ListitemList; 8 9 public List getItemList() {10 return itemList;11 }12 13 public void setItemList(List itemList) {14 this.itemList = itemList;15 }16 17 public static class ItemBean {18 public String getType() {19 return type;20 }21 22 public void setType(String type) {23 this.type = type;24 }25 26 private String type;27 private DataBean data;28 29 public DataBean getData() {30 return data;31 }32 33 public void setData(DataBean data) {34 this.data = data;35 }36 37 public static class DataBean {38 39 private String title;40 private String playUrl;41 42 public String getTitle() {43 return title;44 }45 46 public void setTitle(String title) {47 this.title = title;48 }49 50 public String getPlayUrl() {51 return playUrl;52 }53 54 public void setPlayUrl(String playUrl) {55 this.playUrl = playUrl;56 }57 }58 59 }60 61 }
1 package net.bwie.surfaceviewvideolist.bean; 2 3 public class VideoBean { 4 5 private String title; 6 private String playUrl; 7 8 public VideoBean(String title, String playUrl) { 9 this.title = title;10 this.playUrl = playUrl;11 }12 13 public String getTitle() {14 return title;15 }16 17 public void setTitle(String title) {18 this.title = title;19 }20 21 public String getPlayUrl() {22 return playUrl;23 }24 25 public void setPlayUrl(String playUrl) {26 this.playUrl = playUrl;27 }28 }
Http:
1 package net.bwie.surfaceviewvideolist.httpservice; 2 3 import net.bwie.surfaceviewvideolist.bean.KaiyanBean; 4 5 import retrofit2.Call; 6 import retrofit2.http.GET; 7 8 public interface KaiyanHttpService { 9 10 @GET("api/v4/tabs/selected?udid=11111&vc=168&vn=3.3.1&deviceModel=Huawei%36&first_channel=eyepetizer_baidu_market&last_channel=eyepetizer_baidu_market&system_version_code=20")11 CallgetKaiyanCall();12 13 }
封装类:
1 /** 2 * 能播放视频的SurfaceView,封装MediaPlayer 3 * 提供一个public方法用于设置播放路径和播放的方法 4 */ 5 public class VideoSurfaceView extends SurfaceView implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener { 6 private SurfaceHolder mHolder; 7 private MediaPlayer mMediaPlayer; 8 9 public VideoSurfaceView(Context context, AttributeSet attrs) {10 super(context, attrs);11 12 init();13 }14 15 private void init() {16 // 获得缓冲区持有者17 mHolder = getHolder();18 // 设置生命周期的回调19 mHolder.addCallback(this);20 }21 22 // 设置播放路径并播放23 public void playVideo(String path) {24 if (mMediaPlayer == null) {25 mMediaPlayer = new MediaPlayer();26 // 准备完毕监听器27 mMediaPlayer.setOnPreparedListener(this);28 }29 30 try {31 // 重置MediaPlayer32 mMediaPlayer.reset();33 // 设置画面播放源34 mMediaPlayer.setDisplay(mHolder);35 // 设置播放源36 mMediaPlayer.setDataSource(path);37 // 准备播放38 mMediaPlayer.prepareAsync();39 } catch (Exception e) {40 e.printStackTrace();41 Log.e("1507", e.getMessage());42 }43 44 }45 46 // 停止播放47 public void stop() {48 if (mMediaPlayer != null) {49 mMediaPlayer.stop();50 }51 }52 53 @Override54 public void surfaceCreated(SurfaceHolder holder) {55 56 }57 58 @Override59 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {60 61 }62 63 @Override64 public void surfaceDestroyed(SurfaceHolder holder) {65 if (mMediaPlayer != null) {66 mMediaPlayer.release();// 释放资源67 mMediaPlayer = null;68 }69 }70 71 @Override72 public void onPrepared(MediaPlayer mp) {73 mMediaPlayer.start();74 }75 }
Adapter:
1 public class VideoListAdapter extends RecyclerView.Adapter{ 2 3 private Context mContext; 4 private List mDatas; 5 6 // 记录上一次播放的VideoView 7 private VideoSurfaceView mPlayingView; 8 9 public VideoListAdapter(Context context, List datas) {10 mContext = context;11 mDatas = datas;12 }13 14 @Override15 public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {16 View itemView = LayoutInflater.from(mContext)17 .inflate(R.layout.item_video, parent, false);18 return new ViewHolder(itemView);19 }20 21 @Override22 public void onBindViewHolder(final ViewHolder holder, int position) {23 final VideoBean videoBean = mDatas.get(position);24 25 holder.mTitleTextView.setText(videoBean.getTitle());26 27 // item刚复用进入屏幕时,无论是否播放都停止并隐藏28 holder.mSurfaceView.stop();29 holder.mSurfaceView.setVisibility(View.INVISIBLE);30 31 holder.mPlayBtn.setOnClickListener(new View.OnClickListener() {32 @Override33 public void onClick(View v) {34 35 // 下一次播放时,停止上一次播放36 if (mPlayingView != null) {37 mPlayingView.stop();38 mPlayingView.setVisibility(View.INVISIBLE);39 }40 41 // 播放当前位置的视频42 holder.mSurfaceView.setVisibility(View.VISIBLE);// 显示43 holder.mSurfaceView.playVideo(videoBean.getPlayUrl());44 45 mPlayingView = holder.mSurfaceView;46 }47 });48 }49 50 @Override51 public int getItemCount() {52 return mDatas == null ? 0 : mDatas.size();53 }54 55 static class ViewHolder extends RecyclerView.ViewHolder {56 57 Button mPlayBtn;58 TextView mTitleTextView;59 TextView mProgressTextView;60 VideoSurfaceView mSurfaceView;61 62 public ViewHolder(View itemView) {63 super(itemView);64 65 mPlayBtn = ((Button) itemView.findViewById(R.id.play_btn));66 mTitleTextView = ((TextView) itemView.findViewById(R.id.title_tv));67 mProgressTextView = ((TextView) itemView.findViewById(R.id.progress_tv));68 mSurfaceView = ((VideoSurfaceView) itemView.findViewById(R.id.video_view));69 }70 }71 72 }
别忘了加权限:
1 <uses-permission android:name="android.permission.INTERNET"/>
2 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
导包:
1 compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
2 compile 'com.squareup.retrofit2:converter-gson:2.3.0'
3 compile 'com.squareup.okhttp3:okhttp:3.9.0'
4 compile 'com.github.bumptech.glide:glide:3.8.0'