(仿头条App项目)9.视频列表页面实现

视频列表页面实现

效果图

在这里插入图片描述

相关布局

视频VideoFragment页面放一个ListView存放视频列表
在这里插入图片描述
每条列表布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
        <com.volokh.danylo.video_player_manager.ui.VideoPlayerView
            android:id="@+id/video_view"
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            />
        <ImageView
            android:background="#C00FFF"
            android:id="@+id/cover_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:text="我是标题"
            android:textSize="25sp"
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
</RelativeLayout>

功能实现

引入第三方视频库插件

引入三个依赖,分别是视频管理器,视频列表,因为依赖用到了recyclerview,所以虽然用不到,但是也要导入,否则会报错。
在这里插入图片描述

从服务端获取数据

根据服务端的数据进行解析json,用Gson插件直接快速创建存放视频bean文件VideoData。
在这里插入图片描述
在MyApi中添加获取视频数据地址的方法getVideoData()。
在这里插入图片描述
请求数据

    //2:获取服务端数据
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        System.out.println("VideoFragment onActivityCreated");
        //retrofit ->MyApi
        retrofit.create(MyApi.class).getVideoData().enqueue(new Callback<VideoData>() {
            @Override
            public void onResponse(Call<VideoData> call, Response<VideoData> response) {
                try {
                    System.out.println("VideoFragment onResponse");
                    System.out.println(response.body().data);//json
                    setDataToListView(response.body().data);
                    //# 1:滚动播放列表中心的视频
                    initCalculator();
                    //# 6:添加滚动监听器
                    onListViewScroll();
                    initIndex();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void onFailure(Call<VideoData> call, Throwable t) {
                Toast.makeText(getContext(), "网络异常", Toast.LENGTH_SHORT).show();
            }
        });

    }

显示

编写setDataToListView方法显示视频列表

    //3:显示
    private void setDataToListView(VideoData.VideoBean data) {
        if(listView!=null){

            //做一个数据的转换  VlistBean->MyVideoItem
            for(VideoData.VideoBean.VlistBean video: data.vlist){
                list.add(new MyVideoItem(getContext(),getVideoManager(),video));
            }
            //创建适配器
            //#视频列表:1:添加适配器
            //参1:播放管理者 参2:上下文
            VideoListViewAdapter adapter=new VideoListViewAdapter(getVideoManager(),getContext(),list);
            //设置适配器
            listView.setAdapter(adapter);
        }
    }

这时显示的还只是文字和覆盖的图片,还没有播放功能,下面是滚动播放功能。

滚动播放功能实现

初始化列表索引

    @Override
    public void onResume() {
        super.onResume();
        System.out.println("VideoFragment onResume");
        initIndex();
    }
    private void initIndex() {
        if(!list.isEmpty()){
            listView.post(new Runnable() {
                @Override
                public void run() {
                    //由座标得到item的位置position
                    mListItemVisibilityCalculator.onScrollStateIdle(
                            mItemsPositionGetter,
                            listView.getFirstVisiblePosition(),
                            listView.getLastVisiblePosition());
                }
            });
        }
    }

计算处于列表中间的条目是哪个

    private ListItemsVisibilityCalculator mListItemVisibilityCalculator;
    //# 2:Getter可以获取视频的position
    private ItemsPositionGetter mItemsPositionGetter;
    /*
	# 3:将座标转成position
	记录列表滚动的状态
	    SCROLL_STATE_IDLE:列表停住
	*/
    private int mScrollState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE;
    private void initCalculator() {
        /**
         * 5:用于计算处于列表中间的条目是哪个。
         * 暂停其他视频,播放当前视频
         */
        mListItemVisibilityCalculator =
                new SingleListViewItemActiveCalculator(new DefaultSingleItemCalculatorCallback(), list);

        mItemsPositionGetter = new ListViewItemPositionGetter(listView);
    }

滚动播放

    private void onListViewScroll() {
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // # 6 :记录状态
                mScrollState = scrollState;
                if (scrollState == SCROLL_STATE_IDLE && !list.isEmpty()) { //停止
                    mListItemVisibilityCalculator.onScrollStateIdle(mItemsPositionGetter, view.getFirstVisiblePosition(), view.getLastVisiblePosition());
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (!list.isEmpty()) {
                    //计算可见item的座标
                    System.out.println("mListItemVisibilityCalculator="+mListItemVisibilityCalculator);
                    System.out.println("mItemsPositionGetter="+mItemsPositionGetter);
                    mListItemVisibilityCalculator.onScroll(mItemsPositionGetter, firstVisibleItem, visibleItemCount, mScrollState);
                }
            }
        });
    }

当页面处于后台时,那么停止播放

    @Override
    public void onStop() {
        super.onStop();
        // 如果页面处于后台,那么停止播放
        playerManager.resetMediaPlayer();
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章