• TouTiao开源项目 分析笔记12 从总体到局部 构建视频主页面


    1.构建视频主列表的整体碎片VideoTabLayout

    1.1.首先创建一个VideoTabLayout 

    package com.jasonjan.headnews.module.video;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.design.widget.TabLayout;
    import android.support.v4.app.Fragment;
    import android.support.v4.view.ViewPager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    import com.jasonjan.headnews.R;
    import com.jasonjan.headnews.global.InitApp;
    import com.jasonjan.headnews.adapter.BasePagerAdapter;
    import com.jasonjan.headnews.test.Test_Fragment;
    import com.jasonjan.headnews.util.SettingUtil;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by JasonJan on 2017/12/1.
     */
    
    public class VideoTabLayout extends Fragment {
        private static VideoTabLayout instance = null;
        private static int pageSize = InitApp.AppContext.getResources().getStringArray(R.array.mobile_video_id).length;
        private String categoryId[] = InitApp.AppContext.getResources().getStringArray(R.array.mobile_video_id);
        private String categoryName[] = InitApp.AppContext.getResources().getStringArray(R.array.mobile_video_name);
        private TabLayout tabLayout;
        private ViewPager viewPager;
        private List<Fragment> fragmentList = new ArrayList<>();
        private BasePagerAdapter adapter;
    
        public static VideoTabLayout getInstance() {
            if (instance == null) {
                instance = new VideoTabLayout();
            }
            return instance;
        }
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_video_tab, container, false);
            initView(view);
            initData();
            return view;
        }
    
        @Override
        public void onResume() {
            super.onResume();
            tabLayout.setBackgroundColor(SettingUtil.getInstance().getColor());
        }
    
        private void initView(View view) {
            tabLayout = view.findViewById(R.id.tab_layout_video);
            viewPager = view.findViewById(R.id.view_pager_video);
    
            tabLayout.setupWithViewPager(viewPager);
            tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            tabLayout.setBackgroundColor(SettingUtil.getInstance().getColor());
            viewPager.setOffscreenPageLimit(pageSize);
        }
    
        private void initData() {
            for (int i = 0; i < categoryId.length; i++) {
                Fragment fragment = VideoArticleView.newInstance(categoryId[i]);
                fragmentList.add(fragment);
            }
            adapter = new BasePagerAdapter(getChildFragmentManager(), fragmentList, categoryName);
            viewPager.setAdapter(adapter);
        }
    
        @Override
        public void onDestroy() {
            if (instance != null) {
                instance = null;
            }
            super.onDestroy();
        }
    }

      这里先声明视频中的小碎片名称为:VideoArticleView。

      后面详细分析这个Fragment。主要就是视频的一些小分类。用的是同一种布局方式。

    1.2.这个片段需要一个布局fragment_video_tab.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        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.support.design.widget.TabLayout
            android:id="@+id/tab_layout_video"
            style="@style/TabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            android:theme="@style/AppTheme.AppBarOverlay"
            app:tabTextColor="@color/gray">
        </android.support.design.widget.TabLayout>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager_video"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            tools:layout="@layout/fragment_list">
        </android.support.v4.view.ViewPager>
    
    </LinearLayout>

    1.3.布局真实效果预览

      

    1.4.然后就是上方tablayout中的静态文字

      在资源文件中values中的mobile_video_category.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string-array name="mobile_video_name">
            <item>推荐</item>
            <item>音乐</item>
            <item>搞笑</item>
            <item>社会</item>
            <item>小品</item>
    
            <item>生活</item>
            <item>影视</item>
            <item>娱乐</item>
            <item>呆萌</item>
            <item>游戏</item>
    
            <item>原创</item>
            <item>开眼</item>
    
        </string-array>
    
        <string-array name="mobile_video_id">
            <item>video</item>
            <item>subv_voice</item>
            <item>subv_funny</item>
            <item>subv_society</item>
            <item>subv_comedy</item>
    
            <item>subv_life</item>
            <item>subv_movie</item>
            <item>subv_entertainment</item>
            <item>subv_cute</item>
            <item>subv_game</item>
    
            <item>subv_boutique</item>
            <item>subv_broaden_view</item>
    
        </string-array>
    
    </resources>

    1.5.然后就是将视频主列表的十二种类型用一个BasePagerAdapter联系起来

      下面的代码在上方的VideoTabLayout.java中的一个函数中,这里再重复拿出来讲一下。

     private void initData() {
            for (int i = 0; i < categoryId.length; i++) {
                Fragment fragment = VideoArticleView.newInstance(categoryId[i]);
                fragmentList.add(fragment);
            }
            adapter = new BasePagerAdapter(getChildFragmentManager(), fragmentList, categoryName);
            viewPager.setAdapter(adapter);
        }

      

    1.6.看一下集合所有分类的碎片的适配器==>BasePagerAdapter 

    public class BasePagerAdapter extends FragmentStatePagerAdapter {
    
        private List<Fragment> fragmentList;
        private List<String> titleList;
    
        public BasePagerAdapter(FragmentManager fm, List<Fragment> fragmentList, String[] titles) {
            super(fm);
            this.fragmentList = fragmentList;
            this.titleList = new ArrayList<>(Arrays.asList(titles));
        }
    
        public BasePagerAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> titleList) {
            super(fm);
            this.fragmentList = fragmentList;
            this.titleList = titleList;
        }
    
        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }
    
        @Override
        public int getCount() {
            return titleList.size();
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return titleList.get(position);
        }
    
        @Override
        public int getItemPosition(Object object) {
            return PagerAdapter.POSITION_NONE;
        }
    
        public void recreateItems(List<Fragment> fragmentList, List<String> titleList) {
            this.fragmentList = fragmentList;
            this.titleList = titleList;
            notifyDataSetChanged();
        }
    }

    1.7.第一阶段结束,主要完成了VideoTabLayout这个视频主页面和相应的逻辑。

      第二阶段主要处理12个分片段的布局和逻辑了。


    2.视频系列的文章的基础Bean类

    2.1.第一集团数据返回==>调用API后返回的数据(包括很多杂项)

       /**
         * data : {"status":10,"user_id":"toutiao","video_id":"f2aeddda2a894e53bb3f2cf98994aadb","big_thumbs":[{"img_num":16,"img_url":"https://p1.pstatp.com/origin/19cc000499f3a6986d59","img_x_size":160,"img_y_size":90,"img_x_len":1,"img_y_len":16}],"video_duration":84.8,"video_list":{"video_1":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNWE2YzA4ZmJjZWQxZmIzY2ZhMDdkZGE3Zjg0ZTNkZDUvNThkZGJlMjAvdmlkZW8vbS8xMTQ0YzNiMDAwMDBjMWU1MWIwMWQ1ZjIyMGE0MzMyMTUyNGQwOTQ0MjU5MDI5NmU1NDI3Yjc5NGNlLw==","bitrate":369405,"definition":"360p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzExNDRjM2IwMDAwMGMxZTUxYjAxZDVmMjIwYTQzMzIxNTI0ZDA5NDQyNTkwMjk2ZTU0MjdiNzk0Y2UvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9WWNmakZDNnMxSHFhQ0NxeVZMd3ZkRWNlcXg0JTNE","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":4630326,"socket_buffer":221643000,"user_video_proxy":1,"vheight":360,"vtype":"mp4","vwidth":640},"video_2":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNTk0ZTZjNDZjMjliZDkxY2EwZWJhMTFkM2RlMGIxN2EvNThkZGJlMjAvdmlkZW8vbS8yMjBlNmU2MjY3Mjg4NDU0YzkwOTFjOGYyMTZlZThiOWEwMjExNDRiZjAwMDAwMDZmNTE3YjkxMTk1Lw==","bitrate":577524,"definition":"480p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzIyMGU2ZTYyNjcyODg0NTRjOTA5MWM4ZjIxNmVlOGI5YTAyMTE0NGJmMDAwMDAwNmY1MTdiOTExOTUvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9JTJGbEtPMld4QVVtcUtqUGo4TWw5cFpxaFNSeEklM0Q=","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":6836189,"socket_buffer":346514400,"user_video_proxy":1,"vheight":480,"vtype":"mp4","vwidth":854},"video_3":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNzM4NTJiOTYxNDgyMzc0MDY2NWIyN2VkODZhNWVhMTEvNThkZGJlMjAvdmlkZW8vbS8yMjA0NTViMDUyMjFjYTg0MDAxOWFjZjkwZDNmZGFmZTNhZDExNDQ4ZGMwMDAwMjRkOTFkNmZkNzZhLw==","bitrate":1274484,"definition":"720p","main_url":"aHR0cDovL3YzLjM2NXlnLmNvbS83Mzg1MmI5NjE0ODIzNzQwNjY1YjI3ZWQ4NmE1ZWExMS81OGRkYmUyMC92aWRlby9tLzIyMDQ1NWIwNTIyMWNhODQwMDE5YWNmOTBkM2ZkYWZlM2FkMTE0NDhkYzAwMDAyNGQ5MWQ2ZmQ3NmEv","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":14223659,"socket_buffer":764690400,"user_video_proxy":1,"vheight":720,"vtype":"mp4","vwidth":1280}}}
         * message : success
         * code : 0
         * total : 3
         */

    2.2.第二集团数据返回==>处理上方的data中的数据  

           /**
             * status : 10
             * user_id : toutiao
             * video_id : f2aeddda2a894e53bb3f2cf98994aadb
             * big_thumbs : [{"img_num":16,"img_url":"https://p1.pstatp.com/origin/19cc000499f3a6986d59","img_x_size":160,"img_y_size":90,"img_x_len":1,"img_y_len":16}]
             * video_duration : 84.8
             * video_list : {"video_1":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNWE2YzA4ZmJjZWQxZmIzY2ZhMDdkZGE3Zjg0ZTNkZDUvNThkZGJlMjAvdmlkZW8vbS8xMTQ0YzNiMDAwMDBjMWU1MWIwMWQ1ZjIyMGE0MzMyMTUyNGQwOTQ0MjU5MDI5NmU1NDI3Yjc5NGNlLw==","bitrate":369405,"definition":"360p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzExNDRjM2IwMDAwMGMxZTUxYjAxZDVmMjIwYTQzMzIxNTI0ZDA5NDQyNTkwMjk2ZTU0MjdiNzk0Y2UvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9WWNmakZDNnMxSHFhQ0NxeVZMd3ZkRWNlcXg0JTNE","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":4630326,"socket_buffer":221643000,"user_video_proxy":1,"vheight":360,"vtype":"mp4","vwidth":640},"video_2":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNTk0ZTZjNDZjMjliZDkxY2EwZWJhMTFkM2RlMGIxN2EvNThkZGJlMjAvdmlkZW8vbS8yMjBlNmU2MjY3Mjg4NDU0YzkwOTFjOGYyMTZlZThiOWEwMjExNDRiZjAwMDAwMDZmNTE3YjkxMTk1Lw==","bitrate":577524,"definition":"480p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzIyMGU2ZTYyNjcyODg0NTRjOTA5MWM4ZjIxNmVlOGI5YTAyMTE0NGJmMDAwMDAwNmY1MTdiOTExOTUvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9JTJGbEtPMld4QVVtcUtqUGo4TWw5cFpxaFNSeEklM0Q=","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":6836189,"socket_buffer":346514400,"user_video_proxy":1,"vheight":480,"vtype":"mp4","vwidth":854},"video_3":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNzM4NTJiOTYxNDgyMzc0MDY2NWIyN2VkODZhNWVhMTEvNThkZGJlMjAvdmlkZW8vbS8yMjA0NTViMDUyMjFjYTg0MDAxOWFjZjkwZDNmZGFmZTNhZDExNDQ4ZGMwMDAwMjRkOTFkNmZkNzZhLw==","bitrate":1274484,"definition":"720p","main_url":"aHR0cDovL3YzLjM2NXlnLmNvbS83Mzg1MmI5NjE0ODIzNzQwNjY1YjI3ZWQ4NmE1ZWExMS81OGRkYmUyMC92aWRlby9tLzIyMDQ1NWIwNTIyMWNhODQwMDE5YWNmOTBkM2ZkYWZlM2FkMTE0NDhkYzAwMDAyNGQ5MWQ2ZmQ3NmEv","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":14223659,"socket_buffer":764690400,"user_video_proxy":1,"vheight":720,"vtype":"mp4","vwidth":1280}}
             */

    2.3.整个VideoContentBean类

    package com.jasonjan.headnews.bean.video;
    
    import java.util.List;
    
    /**
     * Created by JasonJan on 2017/12/14.
     */
    
    public class VideoContentBean {
    
        /**
         * data : {"status":10,"user_id":"toutiao","video_id":"f2aeddda2a894e53bb3f2cf98994aadb","big_thumbs":[{"img_num":16,"img_url":"https://p1.pstatp.com/origin/19cc000499f3a6986d59","img_x_size":160,"img_y_size":90,"img_x_len":1,"img_y_len":16}],"video_duration":84.8,"video_list":{"video_1":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNWE2YzA4ZmJjZWQxZmIzY2ZhMDdkZGE3Zjg0ZTNkZDUvNThkZGJlMjAvdmlkZW8vbS8xMTQ0YzNiMDAwMDBjMWU1MWIwMWQ1ZjIyMGE0MzMyMTUyNGQwOTQ0MjU5MDI5NmU1NDI3Yjc5NGNlLw==","bitrate":369405,"definition":"360p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzExNDRjM2IwMDAwMGMxZTUxYjAxZDVmMjIwYTQzMzIxNTI0ZDA5NDQyNTkwMjk2ZTU0MjdiNzk0Y2UvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9WWNmakZDNnMxSHFhQ0NxeVZMd3ZkRWNlcXg0JTNE","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":4630326,"socket_buffer":221643000,"user_video_proxy":1,"vheight":360,"vtype":"mp4","vwidth":640},"video_2":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNTk0ZTZjNDZjMjliZDkxY2EwZWJhMTFkM2RlMGIxN2EvNThkZGJlMjAvdmlkZW8vbS8yMjBlNmU2MjY3Mjg4NDU0YzkwOTFjOGYyMTZlZThiOWEwMjExNDRiZjAwMDAwMDZmNTE3YjkxMTk1Lw==","bitrate":577524,"definition":"480p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzIyMGU2ZTYyNjcyODg0NTRjOTA5MWM4ZjIxNmVlOGI5YTAyMTE0NGJmMDAwMDAwNmY1MTdiOTExOTUvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9JTJGbEtPMld4QVVtcUtqUGo4TWw5cFpxaFNSeEklM0Q=","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":6836189,"socket_buffer":346514400,"user_video_proxy":1,"vheight":480,"vtype":"mp4","vwidth":854},"video_3":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNzM4NTJiOTYxNDgyMzc0MDY2NWIyN2VkODZhNWVhMTEvNThkZGJlMjAvdmlkZW8vbS8yMjA0NTViMDUyMjFjYTg0MDAxOWFjZjkwZDNmZGFmZTNhZDExNDQ4ZGMwMDAwMjRkOTFkNmZkNzZhLw==","bitrate":1274484,"definition":"720p","main_url":"aHR0cDovL3YzLjM2NXlnLmNvbS83Mzg1MmI5NjE0ODIzNzQwNjY1YjI3ZWQ4NmE1ZWExMS81OGRkYmUyMC92aWRlby9tLzIyMDQ1NWIwNTIyMWNhODQwMDE5YWNmOTBkM2ZkYWZlM2FkMTE0NDhkYzAwMDAyNGQ5MWQ2ZmQ3NmEv","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":14223659,"socket_buffer":764690400,"user_video_proxy":1,"vheight":720,"vtype":"mp4","vwidth":1280}}}
         * message : success
         * code : 0
         * total : 3
         */
    
        private DataBean data;
        private String message;
        private int code;
        private int total;
    
        public DataBean getData() {
            return data;
        }
    
        public void setData(DataBean data) {
            this.data = data;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public int getTotal() {
            return total;
        }
    
        public void setTotal(int total) {
            this.total = total;
        }
    
        public static class DataBean {
            /**
             * status : 10
             * user_id : toutiao
             * video_id : f2aeddda2a894e53bb3f2cf98994aadb
             * big_thumbs : [{"img_num":16,"img_url":"https://p1.pstatp.com/origin/19cc000499f3a6986d59","img_x_size":160,"img_y_size":90,"img_x_len":1,"img_y_len":16}]
             * video_duration : 84.8
             * video_list : {"video_1":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNWE2YzA4ZmJjZWQxZmIzY2ZhMDdkZGE3Zjg0ZTNkZDUvNThkZGJlMjAvdmlkZW8vbS8xMTQ0YzNiMDAwMDBjMWU1MWIwMWQ1ZjIyMGE0MzMyMTUyNGQwOTQ0MjU5MDI5NmU1NDI3Yjc5NGNlLw==","bitrate":369405,"definition":"360p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzExNDRjM2IwMDAwMGMxZTUxYjAxZDVmMjIwYTQzMzIxNTI0ZDA5NDQyNTkwMjk2ZTU0MjdiNzk0Y2UvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9WWNmakZDNnMxSHFhQ0NxeVZMd3ZkRWNlcXg0JTNE","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":4630326,"socket_buffer":221643000,"user_video_proxy":1,"vheight":360,"vtype":"mp4","vwidth":640},"video_2":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNTk0ZTZjNDZjMjliZDkxY2EwZWJhMTFkM2RlMGIxN2EvNThkZGJlMjAvdmlkZW8vbS8yMjBlNmU2MjY3Mjg4NDU0YzkwOTFjOGYyMTZlZThiOWEwMjExNDRiZjAwMDAwMDZmNTE3YjkxMTk1Lw==","bitrate":577524,"definition":"480p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzIyMGU2ZTYyNjcyODg0NTRjOTA5MWM4ZjIxNmVlOGI5YTAyMTE0NGJmMDAwMDAwNmY1MTdiOTExOTUvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9JTJGbEtPMld4QVVtcUtqUGo4TWw5cFpxaFNSeEklM0Q=","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":6836189,"socket_buffer":346514400,"user_video_proxy":1,"vheight":480,"vtype":"mp4","vwidth":854},"video_3":{"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNzM4NTJiOTYxNDgyMzc0MDY2NWIyN2VkODZhNWVhMTEvNThkZGJlMjAvdmlkZW8vbS8yMjA0NTViMDUyMjFjYTg0MDAxOWFjZjkwZDNmZGFmZTNhZDExNDQ4ZGMwMDAwMjRkOTFkNmZkNzZhLw==","bitrate":1274484,"definition":"720p","main_url":"aHR0cDovL3YzLjM2NXlnLmNvbS83Mzg1MmI5NjE0ODIzNzQwNjY1YjI3ZWQ4NmE1ZWExMS81OGRkYmUyMC92aWRlby9tLzIyMDQ1NWIwNTIyMWNhODQwMDE5YWNmOTBkM2ZkYWZlM2FkMTE0NDhkYzAwMDAyNGQ5MWQ2ZmQ3NmEv","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":14223659,"socket_buffer":764690400,"user_video_proxy":1,"vheight":720,"vtype":"mp4","vwidth":1280}}
             */
    
            private int status;
            private String user_id;
            private String video_id;
            private double video_duration;
            private VideoListBean video_list;
            private List<BigThumbsBean> big_thumbs;
    
            public int getStatus() {
                return status;
            }
    
            public void setStatus(int status) {
                this.status = status;
            }
    
            public String getUser_id() {
                return user_id;
            }
    
            public void setUser_id(String user_id) {
                this.user_id = user_id;
            }
    
            public String getVideo_id() {
                return video_id;
            }
    
            public void setVideo_id(String video_id) {
                this.video_id = video_id;
            }
    
            public double getVideo_duration() {
                return video_duration;
            }
    
            public void setVideo_duration(double video_duration) {
                this.video_duration = video_duration;
            }
    
            public VideoListBean getVideo_list() {
                return video_list;
            }
    
            public void setVideo_list(VideoListBean video_list) {
                this.video_list = video_list;
            }
    
            public List<BigThumbsBean> getBig_thumbs() {
                return big_thumbs;
            }
    
            public void setBig_thumbs(List<BigThumbsBean> big_thumbs) {
                this.big_thumbs = big_thumbs;
            }
    
            public static class VideoListBean {
                /**
                 * video_1 : {"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNWE2YzA4ZmJjZWQxZmIzY2ZhMDdkZGE3Zjg0ZTNkZDUvNThkZGJlMjAvdmlkZW8vbS8xMTQ0YzNiMDAwMDBjMWU1MWIwMWQ1ZjIyMGE0MzMyMTUyNGQwOTQ0MjU5MDI5NmU1NDI3Yjc5NGNlLw==","bitrate":369405,"definition":"360p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzExNDRjM2IwMDAwMGMxZTUxYjAxZDVmMjIwYTQzMzIxNTI0ZDA5NDQyNTkwMjk2ZTU0MjdiNzk0Y2UvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9WWNmakZDNnMxSHFhQ0NxeVZMd3ZkRWNlcXg0JTNE","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":4630326,"socket_buffer":221643000,"user_video_proxy":1,"vheight":360,"vtype":"mp4","vwidth":640}
                 * video_2 : {"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNTk0ZTZjNDZjMjliZDkxY2EwZWJhMTFkM2RlMGIxN2EvNThkZGJlMjAvdmlkZW8vbS8yMjBlNmU2MjY3Mjg4NDU0YzkwOTFjOGYyMTZlZThiOWEwMjExNDRiZjAwMDAwMDZmNTE3YjkxMTk1Lw==","bitrate":577524,"definition":"480p","main_url":"aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzIyMGU2ZTYyNjcyODg0NTRjOTA5MWM4ZjIxNmVlOGI5YTAyMTE0NGJmMDAwMDAwNmY1MTdiOTExOTUvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9JTJGbEtPMld4QVVtcUtqUGo4TWw5cFpxaFNSeEklM0Q=","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":6836189,"socket_buffer":346514400,"user_video_proxy":1,"vheight":480,"vtype":"mp4","vwidth":854}
                 * video_3 : {"backup_url_1":"aHR0cDovL3Y3LnBzdGF0cC5jb20vNzM4NTJiOTYxNDgyMzc0MDY2NWIyN2VkODZhNWVhMTEvNThkZGJlMjAvdmlkZW8vbS8yMjA0NTViMDUyMjFjYTg0MDAxOWFjZjkwZDNmZGFmZTNhZDExNDQ4ZGMwMDAwMjRkOTFkNmZkNzZhLw==","bitrate":1274484,"definition":"720p","main_url":"aHR0cDovL3YzLjM2NXlnLmNvbS83Mzg1MmI5NjE0ODIzNzQwNjY1YjI3ZWQ4NmE1ZWExMS81OGRkYmUyMC92aWRlby9tLzIyMDQ1NWIwNTIyMWNhODQwMDE5YWNmOTBkM2ZkYWZlM2FkMTE0NDhkYzAwMDAyNGQ5MWQ2ZmQ3NmEv","preload_interval":25,"preload_max_step":10,"preload_min_step":5,"preload_size":327680,"size":14223659,"socket_buffer":764690400,"user_video_proxy":1,"vheight":720,"vtype":"mp4","vwidth":1280}
                 */
    
                private Video1Bean video_1;
                private Video2Bean video_2;
                private Video3Bean video_3;
    
                public Video1Bean getVideo_1() {
                    return video_1;
                }
    
                public void setVideo_1(Video1Bean video_1) {
                    this.video_1 = video_1;
                }
    
                public Video2Bean getVideo_2() {
                    return video_2;
                }
    
                public void setVideo_2(Video2Bean video_2) {
                    this.video_2 = video_2;
                }
    
                public Video3Bean getVideo_3() {
                    return video_3;
                }
    
                public void setVideo_3(Video3Bean video_3) {
                    this.video_3 = video_3;
                }
    
                public static class Video1Bean {
                    /**
                     * backup_url_1 : aHR0cDovL3Y3LnBzdGF0cC5jb20vNWE2YzA4ZmJjZWQxZmIzY2ZhMDdkZGE3Zjg0ZTNkZDUvNThkZGJlMjAvdmlkZW8vbS8xMTQ0YzNiMDAwMDBjMWU1MWIwMWQ1ZjIyMGE0MzMyMTUyNGQwOTQ0MjU5MDI5NmU1NDI3Yjc5NGNlLw==
                     * bitrate : 369405
                     * definition : 360p
                     * main_url : aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzExNDRjM2IwMDAwMGMxZTUxYjAxZDVmMjIwYTQzMzIxNTI0ZDA5NDQyNTkwMjk2ZTU0MjdiNzk0Y2UvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9WWNmakZDNnMxSHFhQ0NxeVZMd3ZkRWNlcXg0JTNE
                     * preload_interval : 25
                     * preload_max_step : 10
                     * preload_min_step : 5
                     * preload_size : 327680
                     * size : 4630326
                     * socket_buffer : 221643000
                     * user_video_proxy : 1
                     * vheight : 360
                     * vtype : mp4
                     * vwidth : 640
                     */
    
                    private String backup_url_1;
                    private int bitrate;
                    private String definition;
                    private String main_url;
                    private int preload_interval;
                    private int preload_max_step;
                    private int preload_min_step;
                    private int preload_size;
                    private int size;
                    private int socket_buffer;
                    private int user_video_proxy;
                    private int vheight;
                    private String vtype;
                    private int vwidth;
    
                    public String getBackup_url_1() {
                        return backup_url_1;
                    }
    
                    public void setBackup_url_1(String backup_url_1) {
                        this.backup_url_1 = backup_url_1;
                    }
    
                    public int getBitrate() {
                        return bitrate;
                    }
    
                    public void setBitrate(int bitrate) {
                        this.bitrate = bitrate;
                    }
    
                    public String getDefinition() {
                        return definition;
                    }
    
                    public void setDefinition(String definition) {
                        this.definition = definition;
                    }
    
                    public String getMain_url() {
                        return main_url;
                    }
    
                    public void setMain_url(String main_url) {
                        this.main_url = main_url;
                    }
    
                    public int getPreload_interval() {
                        return preload_interval;
                    }
    
                    public void setPreload_interval(int preload_interval) {
                        this.preload_interval = preload_interval;
                    }
    
                    public int getPreload_max_step() {
                        return preload_max_step;
                    }
    
                    public void setPreload_max_step(int preload_max_step) {
                        this.preload_max_step = preload_max_step;
                    }
    
                    public int getPreload_min_step() {
                        return preload_min_step;
                    }
    
                    public void setPreload_min_step(int preload_min_step) {
                        this.preload_min_step = preload_min_step;
                    }
    
                    public int getPreload_size() {
                        return preload_size;
                    }
    
                    public void setPreload_size(int preload_size) {
                        this.preload_size = preload_size;
                    }
    
                    public int getSize() {
                        return size;
                    }
    
                    public void setSize(int size) {
                        this.size = size;
                    }
    
                    public int getSocket_buffer() {
                        return socket_buffer;
                    }
    
                    public void setSocket_buffer(int socket_buffer) {
                        this.socket_buffer = socket_buffer;
                    }
    
                    public int getUser_video_proxy() {
                        return user_video_proxy;
                    }
    
                    public void setUser_video_proxy(int user_video_proxy) {
                        this.user_video_proxy = user_video_proxy;
                    }
    
                    public int getVheight() {
                        return vheight;
                    }
    
                    public void setVheight(int vheight) {
                        this.vheight = vheight;
                    }
    
                    public String getVtype() {
                        return vtype;
                    }
    
                    public void setVtype(String vtype) {
                        this.vtype = vtype;
                    }
    
                    public int getVwidth() {
                        return vwidth;
                    }
    
                    public void setVwidth(int vwidth) {
                        this.vwidth = vwidth;
                    }
                }
    
                public static class Video2Bean {
                    /**
                     * backup_url_1 : aHR0cDovL3Y3LnBzdGF0cC5jb20vNTk0ZTZjNDZjMjliZDkxY2EwZWJhMTFkM2RlMGIxN2EvNThkZGJlMjAvdmlkZW8vbS8yMjBlNmU2MjY3Mjg4NDU0YzkwOTFjOGYyMTZlZThiOWEwMjExNDRiZjAwMDAwMDZmNTE3YjkxMTk1Lw==
                     * bitrate : 577524
                     * definition : 480p
                     * main_url : aHR0cDovL3Y2LjM2NXlnLmNvbS92aWRlby9tLzIyMGU2ZTYyNjcyODg0NTRjOTA5MWM4ZjIxNmVlOGI5YTAyMTE0NGJmMDAwMDAwNmY1MTdiOTExOTUvP0V4cGlyZXM9MTQ5MDkzMDczNiZBV1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNb1Myb1BqN2FLWCZTaWduYXR1cmU9JTJGbEtPMld4QVVtcUtqUGo4TWw5cFpxaFNSeEklM0Q=
                     * preload_interval : 25
                     * preload_max_step : 10
                     * preload_min_step : 5
                     * preload_size : 327680
                     * size : 6836189
                     * socket_buffer : 346514400
                     * user_video_proxy : 1
                     * vheight : 480
                     * vtype : mp4
                     * vwidth : 854
                     */
    
                    private String backup_url_1;
                    private int bitrate;
                    private String definition;
                    private String main_url;
                    private int preload_interval;
                    private int preload_max_step;
                    private int preload_min_step;
                    private int preload_size;
                    private int size;
                    private int socket_buffer;
                    private int user_video_proxy;
                    private int vheight;
                    private String vtype;
                    private int vwidth;
    
                    public String getBackup_url_1() {
                        return backup_url_1;
                    }
    
                    public void setBackup_url_1(String backup_url_1) {
                        this.backup_url_1 = backup_url_1;
                    }
    
                    public int getBitrate() {
                        return bitrate;
                    }
    
                    public void setBitrate(int bitrate) {
                        this.bitrate = bitrate;
                    }
    
                    public String getDefinition() {
                        return definition;
                    }
    
                    public void setDefinition(String definition) {
                        this.definition = definition;
                    }
    
                    public String getMain_url() {
                        return main_url;
                    }
    
                    public void setMain_url(String main_url) {
                        this.main_url = main_url;
                    }
    
                    public int getPreload_interval() {
                        return preload_interval;
                    }
    
                    public void setPreload_interval(int preload_interval) {
                        this.preload_interval = preload_interval;
                    }
    
                    public int getPreload_max_step() {
                        return preload_max_step;
                    }
    
                    public void setPreload_max_step(int preload_max_step) {
                        this.preload_max_step = preload_max_step;
                    }
    
                    public int getPreload_min_step() {
                        return preload_min_step;
                    }
    
                    public void setPreload_min_step(int preload_min_step) {
                        this.preload_min_step = preload_min_step;
                    }
    
                    public int getPreload_size() {
                        return preload_size;
                    }
    
                    public void setPreload_size(int preload_size) {
                        this.preload_size = preload_size;
                    }
    
                    public int getSize() {
                        return size;
                    }
    
                    public void setSize(int size) {
                        this.size = size;
                    }
    
                    public int getSocket_buffer() {
                        return socket_buffer;
                    }
    
                    public void setSocket_buffer(int socket_buffer) {
                        this.socket_buffer = socket_buffer;
                    }
    
                    public int getUser_video_proxy() {
                        return user_video_proxy;
                    }
    
                    public void setUser_video_proxy(int user_video_proxy) {
                        this.user_video_proxy = user_video_proxy;
                    }
    
                    public int getVheight() {
                        return vheight;
                    }
    
                    public void setVheight(int vheight) {
                        this.vheight = vheight;
                    }
    
                    public String getVtype() {
                        return vtype;
                    }
    
                    public void setVtype(String vtype) {
                        this.vtype = vtype;
                    }
    
                    public int getVwidth() {
                        return vwidth;
                    }
    
                    public void setVwidth(int vwidth) {
                        this.vwidth = vwidth;
                    }
                }
    
                public static class Video3Bean {
                    /**
                     * backup_url_1 : aHR0cDovL3Y3LnBzdGF0cC5jb20vNzM4NTJiOTYxNDgyMzc0MDY2NWIyN2VkODZhNWVhMTEvNThkZGJlMjAvdmlkZW8vbS8yMjA0NTViMDUyMjFjYTg0MDAxOWFjZjkwZDNmZGFmZTNhZDExNDQ4ZGMwMDAwMjRkOTFkNmZkNzZhLw==
                     * bitrate : 1274484
                     * definition : 720p
                     * main_url : aHR0cDovL3YzLjM2NXlnLmNvbS83Mzg1MmI5NjE0ODIzNzQwNjY1YjI3ZWQ4NmE1ZWExMS81OGRkYmUyMC92aWRlby9tLzIyMDQ1NWIwNTIyMWNhODQwMDE5YWNmOTBkM2ZkYWZlM2FkMTE0NDhkYzAwMDAyNGQ5MWQ2ZmQ3NmEv
                     * preload_interval : 25
                     * preload_max_step : 10
                     * preload_min_step : 5
                     * preload_size : 327680
                     * size : 14223659
                     * socket_buffer : 764690400
                     * user_video_proxy : 1
                     * vheight : 720
                     * vtype : mp4
                     * vwidth : 1280
                     */
    
                    private String backup_url_1;
                    private int bitrate;
                    private String definition;
                    private String main_url;
                    private int preload_interval;
                    private int preload_max_step;
                    private int preload_min_step;
                    private int preload_size;
                    private int size;
                    private int socket_buffer;
                    private int user_video_proxy;
                    private int vheight;
                    private String vtype;
                    private int vwidth;
    
                    public String getBackup_url_1() {
                        return backup_url_1;
                    }
    
                    public void setBackup_url_1(String backup_url_1) {
                        this.backup_url_1 = backup_url_1;
                    }
    
                    public int getBitrate() {
                        return bitrate;
                    }
    
                    public void setBitrate(int bitrate) {
                        this.bitrate = bitrate;
                    }
    
                    public String getDefinition() {
                        return definition;
                    }
    
                    public void setDefinition(String definition) {
                        this.definition = definition;
                    }
    
                    public String getMain_url() {
                        return main_url;
                    }
    
                    public void setMain_url(String main_url) {
                        this.main_url = main_url;
                    }
    
                    public int getPreload_interval() {
                        return preload_interval;
                    }
    
                    public void setPreload_interval(int preload_interval) {
                        this.preload_interval = preload_interval;
                    }
    
                    public int getPreload_max_step() {
                        return preload_max_step;
                    }
    
                    public void setPreload_max_step(int preload_max_step) {
                        this.preload_max_step = preload_max_step;
                    }
    
                    public int getPreload_min_step() {
                        return preload_min_step;
                    }
    
                    public void setPreload_min_step(int preload_min_step) {
                        this.preload_min_step = preload_min_step;
                    }
    
                    public int getPreload_size() {
                        return preload_size;
                    }
    
                    public void setPreload_size(int preload_size) {
                        this.preload_size = preload_size;
                    }
    
                    public int getSize() {
                        return size;
                    }
    
                    public void setSize(int size) {
                        this.size = size;
                    }
    
                    public int getSocket_buffer() {
                        return socket_buffer;
                    }
    
                    public void setSocket_buffer(int socket_buffer) {
                        this.socket_buffer = socket_buffer;
                    }
    
                    public int getUser_video_proxy() {
                        return user_video_proxy;
                    }
    
                    public void setUser_video_proxy(int user_video_proxy) {
                        this.user_video_proxy = user_video_proxy;
                    }
    
                    public int getVheight() {
                        return vheight;
                    }
    
                    public void setVheight(int vheight) {
                        this.vheight = vheight;
                    }
    
                    public String getVtype() {
                        return vtype;
                    }
    
                    public void setVtype(String vtype) {
                        this.vtype = vtype;
                    }
    
                    public int getVwidth() {
                        return vwidth;
                    }
    
                    public void setVwidth(int vwidth) {
                        this.vwidth = vwidth;
                    }
                }
            }
    
            public static class BigThumbsBean {
                /**
                 * img_num : 16
                 * img_url : https://p1.pstatp.com/origin/19cc000499f3a6986d59
                 * img_x_size : 160
                 * img_y_size : 90
                 * img_x_len : 1
                 * img_y_len : 16
                 */
    
                private int img_num;
                private String img_url;
                private int img_x_size;
                private int img_y_size;
                private int img_x_len;
                private int img_y_len;
    
                public int getImg_num() {
                    return img_num;
                }
    
                public void setImg_num(int img_num) {
                    this.img_num = img_num;
                }
    
                public String getImg_url() {
                    return img_url;
                }
    
                public void setImg_url(String img_url) {
                    this.img_url = img_url;
                }
    
                public int getImg_x_size() {
                    return img_x_size;
                }
    
                public void setImg_x_size(int img_x_size) {
                    this.img_x_size = img_x_size;
                }
    
                public int getImg_y_size() {
                    return img_y_size;
                }
    
                public void setImg_y_size(int img_y_size) {
                    this.img_y_size = img_y_size;
                }
    
                public int getImg_x_len() {
                    return img_x_len;
                }
    
                public void setImg_x_len(int img_x_len) {
                    this.img_x_len = img_x_len;
                }
    
                public int getImg_y_len() {
                    return img_y_len;
                }
    
                public void setImg_y_len(int img_y_len) {
                    this.img_y_len = img_y_len;
                }
            }
        }
    }
    View Code

      这个类比较庞大,都是按照服务器返回的数据而对应建立的。 


    3.视频系列的视图以及处理器控制

    3.1.最底层视图以及处理器接口

    public interface IVideoArticle {
    
        interface View extends IBaseListView<Presenter> {
    
            /**
             * 请求数据
             */
            void onLoadData();
        }
    
        interface Presenter extends IBasePresenter {
    
            /**
             * 请求数据
             */
            void doLoadData(String... category);
    
            /**
             * 再起请求数据
             */
            void doLoadMoreData();
    
            /**
             * 设置适配器
             */
            void doSetAdapter(List<MultiNewsArticleDataBean> dataBeen);
        }
    }

    3.2.视频系列的视图

    package com.jasonjan.headnews.module.video;
    
    import android.os.Bundle;
    import android.view.View;
    
    import com.jasonjan.headnews.adapter.DiffCallback;
    import com.jasonjan.headnews.bean.common.LoadingBean;
    import com.jasonjan.headnews.main.Register;
    import com.jasonjan.headnews.module.base.BaseListFragment;
    import com.jasonjan.headnews.util.OnLoadMoreListener;
    
    import java.util.List;
    
    import me.drakeet.multitype.Items;
    import me.drakeet.multitype.MultiTypeAdapter;
    
    /**
     * Created by JasonJan on 2017/12/14.
     */
    
    public class VideoArticleView extends BaseListFragment<IVideoArticle.Presenter> implements IVideoArticle.View {
        private static final String TAG="VideoArticleView";
        private String categoryId;
    
        public static VideoArticleView newInstance(String categoryId){
            Bundle bundle=new Bundle();
            bundle.putString(TAG,categoryId);
            VideoArticleView videoArticleView=new VideoArticleView();
            videoArticleView.setArguments(bundle);
            return videoArticleView;
        }
    
        @Override
        protected void initData() {
            categoryId = getArguments().getString(TAG);
        }
    
        @Override
        protected void initView(View view){
            super.initView(view);
            super.initView(view);
            adapter = new MultiTypeAdapter(oldItems);
            Register.registerVideoArticleItem(adapter);
            recyclerView.setAdapter(adapter);
            recyclerView.addOnScrollListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    if (canLoadMore) {
                        canLoadMore = false;
                        presenter.doLoadMoreData();
                    }
                }
            });
        }
    
        @Override
        public void fetchData() {
            super.fetchData();
            onLoadData();
        }
    
        @Override
        public void onLoadData() {
            onShowLoading();
            presenter.doLoadData(categoryId);
        }
    
        @Override
        public void onSetAdapter(final List<?> list) {
            Items newItems = new Items(list);
            newItems.add(new LoadingBean());
            DiffCallback.notifyDataSetChanged(oldItems, newItems, DiffCallback.MUlTI_NEWS, adapter);
            oldItems.clear();
            oldItems.addAll(newItems);
            canLoadMore = true;
        }
    
        /**
         * API 跟新闻的一样 所以采用类似新闻的 presenter
         *
         * @param presenter
         */
        @Override
        public void setPresenter(IVideoArticle.Presenter presenter) {
            if (null == presenter) {
                this.presenter = new VideoArticlePresenter(this);
            }
        }
    }

      然后发现处理器还没有设置呢。

      然后还有视图绑定也未实现(在自定义的Register中实现)

      然后还有处理新老数据来刷新(在自定义的Diffback中实现)

    3.3.视频系列的处理器

      这个处理器可以就用新闻页面通用的一个处理器

      不过我还是自己另外写了一个处理器

      和新闻页面的处理器非常相似。

    package com.jasonjan.headnews.module.video;
    
    import android.text.TextUtils;
    
    import com.google.gson.Gson;
    import com.jasonjan.headnews.bean.news.MultiNewsArticleBean;
    import com.jasonjan.headnews.bean.news.MultiNewsArticleDataBean;
    import com.jasonjan.headnews.main.ErrorAction;
    import com.jasonjan.headnews.main.RetrofitFactory;
    import com.jasonjan.headnews.util.TimeUtil;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import io.reactivex.Observable;
    import io.reactivex.annotations.NonNull;
    import io.reactivex.functions.Consumer;
    import io.reactivex.functions.Function;
    import io.reactivex.functions.Predicate;
    import io.reactivex.schedulers.Schedulers;
    
    /**
     * Created by JasonJan on 2017/12/14.
     */
    
    public class VideoArticlePresenter implements IVideoArticle.Presenter{
        private static final String TAG = "VideoArticlePresenter";
        private IVideoArticle.View view;
        private String category;
        private String time;
        private Gson gson = new Gson();
        private List<MultiNewsArticleDataBean> dataList = new ArrayList<>();
    
        VideoArticlePresenter(IVideoArticle.View view) {
            this.view = view;
            this.time = TimeUtil.getCurrentTimeStamp();
        }
    
        @Override
        public void doLoadData(String... category){
            try {
                if (null == this.category) {
                    this.category = category[0];
                }
            } catch (Exception e) {
                ErrorAction.print(e);
            }
    
            // 释放内存
            if (dataList.size() > 100) {
                dataList.clear();
            }
    
            RetrofitFactory.getRetrofit().create(IMobileVideoApi.class)
                    .getVideoArticle(this.category, time)
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .switchMap(new Function<MultiNewsArticleBean, Observable<MultiNewsArticleDataBean>>() {
                        @Override
                        public Observable<MultiNewsArticleDataBean> apply(@NonNull MultiNewsArticleBean multiNewsArticleBean) throws Exception {
                            List<MultiNewsArticleDataBean> dataList = new ArrayList<>();
                            for (MultiNewsArticleBean.DataBean dataBean : multiNewsArticleBean.getData()) {
                                dataList.add(gson.fromJson(dataBean.getContent(), MultiNewsArticleDataBean.class));
                            }
                            return Observable.fromIterable(dataList);
                        }
                    })
                    .filter(new Predicate<MultiNewsArticleDataBean>() {
                        @Override
                        public boolean test(@NonNull MultiNewsArticleDataBean dataBean) throws Exception {
                            time = dataBean.getBehot_time();
                            if (TextUtils.isEmpty(dataBean.getSource())) {
                                return false;
                            }
                            try {
                                // 过滤头条问答新闻
                                if (dataBean.getSource().contains("头条问答")
                                        || dataBean.getTag().contains("ad")
                                        || dataBean.getSource().contains("话题")) {
                                    return false;
                                }
                            } catch (NullPointerException e) {
                                ErrorAction.print(e);
                            }
                            // 过滤重复新闻(与上次刷新的数据比较)
                            for (MultiNewsArticleDataBean bean : dataList) {
                                if (bean.getTitle().equals(dataBean.getTitle())) {
                                    return false;
                                }
                            }
                            return true;
                        }
                    })
                    .toList()
                    .compose(view.<List<MultiNewsArticleDataBean>>bindToLife())
                    .subscribe(new Consumer<List<MultiNewsArticleDataBean>>() {
                        @Override
                        public void accept(@NonNull List<MultiNewsArticleDataBean> list) throws Exception {
                            doSetAdapter(list);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            doShowNetError();
                            ErrorAction.print(throwable);
                        }
                    });
    
        }
    
        @Override
        public void doLoadMoreData() {
            doLoadData();
        }
    
        @Override
        public void doSetAdapter(List<MultiNewsArticleDataBean> dataBeen) {
            dataList.addAll(dataBeen);
            view.onSetAdapter(dataList);
            view.onHideLoading();
        }
    
        @Override
        public void doRefresh() {
            if (dataList.size() != 0) {
                dataList.clear();
                time = TimeUtil.getCurrentTimeStamp();
            }
            doLoadData();
        }
    
        @Override
        public void doShowNetError() {
            view.onHideLoading();
            view.onShowNetError();
        }
    
    }

    3.4.视频系列文章的API请求

    public interface IMobileVideoApi {
    
        /**
         * 获取视频标题等信息
         * http://is.snssdk.com/api/news/feed/v53/?category=subv_cute&refer=1&count=20&max_behot_time=1499321562&iid=11776029171&device_id=36394312781
         */
        @GET("http://is.snssdk.com/api/news/feed/v62/?iid=5034850950&device_id=6096495334&refer=1&count=20&aid=13")
        Observable<MultiNewsArticleBean> getVideoArticle(
                @Query("category") String category,
                @Query("max_behot_time") String maxBehotTime);
    
        /**
         * 获取视频信息
         * Api 生成较复杂 详情查看 
         * http://ib.365yg.com/video/urls/v/1/toutiao/mp4/视频ID?r=17位随机数&s=加密结果
         */
        @GET
        Observable<VideoContentBean> getVideoContent(@Url String url);
    }

      可以看到,请求视频的地址和请求之前新闻的网址是一样的

      而且返回数据也一样==>Observable<MultiNewsArticleBean>

      当然唯一不同的应该就是这个category,

      如果带了这个参数,我猜想应该返回的东西都有带有视频的图片。

    3.5.然后在Register类中注入数据类型 

    /**
         * 注入视频类型
         * @param adapter
         */
        public static void registerVideoArticleItem(@NonNull MultiTypeAdapter adapter) {
            adapter.register(MultiNewsArticleDataBean.class, new NewsArticleVideoViewBinder());
            adapter.register(LoadingBean.class, new LoadingViewBinder());
            adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
        }

    3.6.最后再DiffCallback中加视频类型

      在areItemsTheSame函数中添加Video类型。

      因为类型和Multi_News一样,用这个代替也一样。

    case MUlTI_NEWS:
                        return ((MultiNewsArticleDataBean) oldList.get(oldItemPosition)).getTitle().equals(
                                ((MultiNewsArticleDataBean) newList.get(newItemPosition)).getTitle());

      在areContentsTheSame中添加这个类型。

    case MUlTI_NEWS:
                        return ((MultiNewsArticleDataBean) oldList.get(oldItemPosition)).getItem_id() ==
                                ((MultiNewsArticleDataBean) newList.get(newItemPosition)).getItem_id();


    4.视图绑定类

    4.1.视图绑定类的布局定义==>item_news_article_video.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
        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="wrap_content"
        android:layout_marginBottom="4dp"
        android:layout_marginTop="4dp"
        android:background="@color/viewBackground"
        app:cardElevation="1dp">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/selectableItemBackground"
            android:foreground="?attr/selectableItemBackground"
            android:padding="16dp">
    
            <LinearLayout
                android:id="@+id/header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:orientation="horizontal">
    
                <com.jasonjan.headnews.widget.CircleImageView
                    android:id="@+id/iv_media"
                    android:layout_width="22dp"
                    android:layout_height="22dp"
                    android:scaleType="centerCrop"/>
    
                <TextView
                    android:id="@+id/tv_extra"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="8dp"
                    android:layout_marginStart="8dp"
                    android:ellipsize="end"
                    android:maxLength="30"
                    android:maxLines="1"
                    android:textAppearance="@style/TextAppearance.AppCompat.Caption"
                    tools:text="新闻源 - 2222条评论 - 1小时前"/>
    
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
    
                    <ImageView
                        android:id="@+id/iv_dots"
                        android:layout_width="22dp"
                        android:layout_height="22dp"
                        android:layout_alignParentEnd="true"
                        android:layout_alignParentRight="true"
                        android:layout_centerVertical="true"
                        android:padding="4dp"
                        android:scaleType="center"
                        app:srcCompat="@drawable/ic_dots_horizontal_grey500_24dp"
                        tools:ignore="ContentDescription"/>
                </RelativeLayout>
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/header"
                android:layout_marginTop="4dp"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/tv_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:maxLines="2"
                    android:textStyle="bold"
                    tools:text="菲总统称中国将向菲提供武器 已指示军方前往接收"/>
    
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="169dp"
                    android:paddingTop="8dp">
    
                    <ImageView
                        android:id="@+id/iv_video_image"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:scaleType="centerCrop"
                        android:src="@color/viewBackground"
                        tools:ignore="ContentDescription"/>
    
                    <TextView
                        android:id="@+id/tv_video_time"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentBottom="true"
                        android:layout_alignParentEnd="true"
                        android:layout_alignParentRight="true"
                        android:layout_marginBottom="8dp"
                        android:layout_marginEnd="8dp"
                        android:layout_marginRight="8dp"
                        android:background="@color/textColorPrimary"
                        android:padding="2dp"
                        android:textColor="@color/White"
                        tools:text="10:34"/>
    
                </RelativeLayout>
    
            </LinearLayout>
        </RelativeLayout>
    </android.support.v7.widget.CardView>

    4.2.视图效果

      

    4.3.视图绑定类

    public class NewsArticleVideoViewBinder extends ItemViewBinder<MultiNewsArticleDataBean,NewsArticleVideoViewBinder.ViewHolder> {
    
        private static final String TAG = "NewsArticleHasVideoView";
    
        @NonNull
        @Override
        protected NewsArticleVideoViewBinder.ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
            View view = inflater.inflate(R.layout.item_news_article_video, parent, false);
            return new ViewHolder(view);
        }
    
        @Override
        protected void onBindViewHolder(@NonNull final NewsArticleVideoViewBinder.ViewHolder holder, @NonNull final MultiNewsArticleDataBean item) {
    
            final Context context = holder.itemView.getContext();
    
            try {
                if (null != item.getVideo_detail_info()) {
                    if (null != item.getVideo_detail_info().getDetail_video_large_image()) {
                        String image = item.getVideo_detail_info().getDetail_video_large_image().getUrl();
                        if (!TextUtils.isEmpty(image)) {
                            ImageLoader.loadCenterCrop(context, image, holder.iv_video_image, R.color.viewBackground, R.mipmap.error_image);
                        }
                    }
                } else {
                    holder.iv_video_image.setImageResource(R.mipmap.error_image);
                }
    
                if (null != item.getUser_info()) {
                    String avatar_url = item.getUser_info().getAvatar_url();
                    if (!TextUtils.isEmpty(avatar_url)) {
                        ImageLoader.loadCenterCrop(context, avatar_url, holder.iv_media, R.color.viewBackground);
                    }
                }
    
                String tv_title = item.getTitle();
                holder.tv_title.setTextSize(SettingUtil.getInstance().getTextSize());
                String tv_source = item.getSource();
                String tv_comment_count = item.getComment_count() + "评论";
                String tv_datetime = item.getBehot_time() + "";
                if (!TextUtils.isEmpty(tv_datetime)) {
                    tv_datetime = TimeUtil.getTimeStampAgo(tv_datetime);
                }
                int video_duration = item.getVideo_duration();
                String min = String.valueOf(video_duration / 60);
                String second = String.valueOf(video_duration % 10);
                if (Integer.parseInt(second) < 10) {
                    second = "0" + second;
                }
                String tv_video_time = min + ":" + second;
    
                holder.tv_title.setText(tv_title);
                holder.tv_extra.setText(tv_source + " - " + tv_comment_count + " - " + tv_datetime);
                holder.tv_video_time.setText(tv_video_time);
                holder.iv_dots.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        PopupMenu popupMenu = new PopupMenu(context,
                                holder.iv_dots, Gravity.END, 0, R.style.MyPopupMenu);
                        popupMenu.inflate(R.menu.menu_share);
                        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem menu) {
                                int itemId = menu.getItemId();
                                if (itemId == R.id.action_share) {
                                    IntentAction.send(context, item.getTitle() + "
    " + item.getShare_url());
                                }
                                return false;
                            }
                        });
                        popupMenu.show();
                    }
                });
    
                RxView.clicks(holder.itemView)
                        .throttleFirst(1, TimeUnit.SECONDS)
                        .subscribe(new Consumer<Object>() {
                            @Override
                            public void accept(@io.reactivex.annotations.NonNull Object o) throws Exception {
                               // VideoContentActivity.launch(item);
                            }
                        });
            } catch (Exception e) {
                ErrorAction.print(e);
            }
        }
    
    
        class ViewHolder extends RecyclerView.ViewHolder {
    
            private CircleImageView iv_media;
            private TextView tv_extra;
            private TextView tv_title;
            private ImageView iv_video_image;
            private TextView tv_video_time;
            private ImageView iv_dots;
    
            ViewHolder(View itemView) {
                super(itemView);
                this.iv_media = itemView.findViewById(R.id.iv_media);
                this.tv_extra = itemView.findViewById(R.id.tv_extra);
                this.tv_title = itemView.findViewById(R.id.tv_title);
                this.iv_video_image = itemView.findViewById(R.id.iv_video_image);
                this.tv_video_time = itemView.findViewById(R.id.tv_video_time);
                this.iv_dots = itemView.findViewById(R.id.iv_dots);
            }
        }
    }

      这个绑定类和新闻中的页面的其中一种类型完全一样。

      因为新闻页面中有3种类型,一种纯文字,一种图片,一种视频。

      这里就直接用新闻中的视频的绑定类即可。

      因为API也是用的新闻

      可以说视频这个大类,就是从新闻中筛选出的视频类型。

      通过传入的一个参数category,返回的全是视频。


    5.目前效果预览

    5.1.目前完成的工作

      新闻的三种大类型

      图片的一种大类型,这种大类型有4个分类,为全部、老照片、故事照片和摄影集。

      视频采用的是新闻中的其中一种大类型,所以直接用新闻中的绑定类即可,API也一样的。

      但是每种类型的评论以及详细页面还未实现。

    5.2.手机真实数据预览

      

      



    既然选择了,便不顾风雨兼程。Just follow yourself.
  • 相关阅读:
    ztz11的noip模拟赛T3:评分系统
    20181030NOIP模拟赛T3
    20181030NOIP模拟赛T2
    20181030noip模拟赛T1
    20181029NOIP模拟赛T3
    20181029NOIP模拟赛T2
    20181029noip模拟赛T1
    最优贸易(tarjan,spfa)
    [ZJOI2009]假期的宿舍(二分图匹配)
    上白泽慧音(tarjan,图的染色)
  • 原文地址:https://www.cnblogs.com/Jason-Jan/p/8036794.html
Copyright © 2020-2023  润新知