优秀案例

记录一次完美解决双瀑布流!!!!

2020-05-09  本文已影响0人  朱_c713

完美解决双瀑布流!!!!——前后的对比建议使用对比软件观看

项目 需求:

  1. 首页列表中有两个瀑布流
  2. 服务器无法将两个接口写在同一个接口中。


    image.png

项目要求:

  1. 两个瀑布流自由上拉加载无问题。
  2. 列表要流畅

解决方案一:首页中采用两个RecyclerView,采用普通写法。

用nestScrollView解决滑动冲突:

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv_child_Push"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingStart="@dimen/space_30"
                    android:paddingEnd="@dimen/space_30"
                    android:visibility="visible" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv_pu_bu"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </androidx.core.widget.NestedScrollView>

结果:瀑布流一起请求完,无上拉加载效果。滑动卡顿。因为view未能得到复用。

原因:这是因为NestedScrollView 本身实现的有ScrollView相关的接口(结合Baskquickadapter)自己内部会测量和计算。Scrollview,所有的子view都会一次性被加载出来。。

解决方案二:第一个Recyclerview作为header或者footer,添加到第二个RecyclerView

结果:作为header和Footer的View,无法一次请求,也么有上拉加载效果。

原因:同样是因为header是一次加载完的原因。
我们采用第一个Recylcerview,作为header添加到第二个RecyclerView中的办法。
但是第一个的下拉刷新还是无法实现。

解决方案三:第二个RecyclerView的Item 作为第一个RecyclerView的 多条目布局中的一种条目处理。

当第一个数据的接口拉到最后一页的时候,请求第二个数据,拼接到前面就像使用第一个数据一样。

具体操作和重构流程:

  1. 两个adapter统一为一个,第二个的请求httpPager2的成功方法的数据格式发生变化。

  2. 第二个RecyclerView的LayoutManger与第一个保持一致。

  3. 在第一个瀑布流加载结束的位置,做衔接处理

  4. 下拉刷新的位置,重新添加page,并改变状态。

1) 删除一下bottomAdapter相关的方法
      bottomAdapter.setLoadMoreView(new LoadingAddDataView());
        bottomAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                JumpUtils.jumpToPlayerAct(bottomData.get(position).getVod_id());
            }
        });
        bottomAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                httpPager2();
            }
        }, rv_pu_bu);
2)两个数据衔接位置的演变:

原来1


   GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page >= body.getLast_page()) {
                    mainAdapter.loadMoreEnd(true);
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }

演变2:


  GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page >= body.getLast_page()) {
                    currentRequest = "httpPager2";
                    httpPager2();
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }

演变3:
解决第二个瀑布流的第一页一闪而过,看不到的问题。

  GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page == body.getLast_page()) {
                    mainAdapter.loadMoreComplete();
                    currentRequest = "httpPager2";
                    httpPager2();
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }
3) 添加请求变化的标志位,数据变化的时候改变这个。
 public String currentRequest = "httpPager";

下拉的时候,根据标志位决定该请求那个;

   mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                if ("httpPager".equals(currentRequest)) {
                    httpPager();
                } else {
                    httpPager2();
                }

            }
        }, rv_child_Push);

新版核心代码——请使用对比软件,观察两个的不同:

核心代码:只记录有差异的代码,属于代码片段

public class ChildRecommendFragment  {

    @BindView(R.id.sl_Push)
    SwipeRefreshLayout sl_Push;

    @BindView(R.id.rv_child_Push)
    RecyclerView rv_child_Push;


    @BindView(R.id.loading)
    View loading;


    @BindView(R.id.load_err)
    View load_err;


    /**
     * 上拉加载页数
     */
    public int pagePullRefresh = 1;
    public int page = 1;
    public int page2 = 1;

  

    private RecommendAdapter mainAdapter;
    private ArrayList<PushMultipleItem> multipleList = new ArrayList<>();

    public String currentRequest = "httpPager";


    @Override
    protected void initView() {
       
        LinearLayoutManager manager = new LinearLayoutManager(mActivity);
        rv_child_Push.setLayoutManager(manager);
        mainAdapter = new RecommendAdapter(null);
        rv_child_Push.setAdapter(mainAdapter);  
        //上拉加载
        mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                if ("httpPager".equals(currentRequest)) {
                    httpPager();
                } else {
                    httpPager2();
                }

            }
        }, rv_child_Push);

        sl_Push.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                pagePullRefresh = getRandomPageRefresh();
                page = 1;
                page2=1;
                currentRequest="httpPager";
                httpData();
            }
        });

        load_err.setOnClickListener(view -> {
            loading.setVisibility(View.VISIBLE);
            load_err.setVisibility(View.GONE);
            page = 1;
            page2=1;
            currentRequest="httpPager";
            httpData();
        });
    }

    @Override
    protected void initData() {
        loading.setVisibility(View.VISIBLE);
        httpData();
    }

     * 请求数据集合
     */
    private void httpData() {

        String url = ConstantUtils.getUrlConstant().video_type
                + "?type_id=" + getArguments().get("id")
                + "&version=" + AppUtils.getAppVersionCode()
                + "&page=" + pagePullRefresh
                + "&mobiletype=1";

        OkGoUtils.getRequest(url, new JsonCallBack<GetTypeDetailBean>(GetTypeDetailBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeDetailBean, ? extends Request> request) {

            }

            @Override
            public void onSuccess(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                load_err.setVisibility(View.GONE);
                clearList();
                sl_Push.setRefreshing(false);
                GetTypeDetailBean body = response.body();               
                multipleList = bornMultipleList(body);
                mainAdapter.setNewData(multipleList);

            }

            @Override
            public void onError(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                sl_Push.setRefreshing(false);
                ToastUtils.showShort("连接服务器失败");
                if (mainAdapter.getData().size() == 0) {
                    load_err.setVisibility(View.VISIBLE);
                }
            }         
        });
    }



    private ArrayList<PushMultipleItem> bornMultipleList(GetTypeDetailBean body) {
        ArrayList<PushMultipleItem> multipleList = new ArrayList<>();
        GetTypeDetailBean.RenhotBean renhot = body.getRenhot();
        VideoBean recentTitleBean = new VideoBean(ConstantUtils.RECENT_ID, ConstantUtils.RECENT_VALUE);
        VideoBean hotTitleBean = new VideoBean(ConstantUtils.HITS_ID, ConstantUtils.HITS_VALUE);
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, recentTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.RECENT_KEY, renhot.getRecent()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.RECENT_KEY, null));
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, hotTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.HITS_KEY, renhot.getHits()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.HITS_KEY, null));

        return multipleList;
    }



    private void clearList() {
        if (multipleList != null && multipleList.size() > 0) {
            multipleList.clear();
        }
    }


    /**
     * 分页请求
     */
    private void httpPager() {
        OkGoUtils.getRequest(getUrl(), new JsonCallBack<GetTypeVodsBean>(GetTypeVodsBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeVodsBean, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<GetTypeVodsBean> response) {

                GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page == body.getLast_page()) {
                    mainAdapter.loadMoreComplete();
                    currentRequest = "httpPager2";
                    httpPager2();
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<GetTypeVodsBean> response) {
                mainAdapter.loadMoreFail();
            }

        
        });
    }

    @NotNull
    private String getUrl() {
        return ConstantUtils.getUrlConstant().getypevods
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page;
    }

    private void httpPager2() {
        String url = ConstantUtils.getUrlConstant().getrecentvod
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page2;

        OkGoUtils.getRequest(url, new JsonCallBack<VideoBeanBottom>(VideoBeanBottom.class, mActivity) {
            @Override
            public void onStart(Request<VideoBeanBottom, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<VideoBeanBottom> response) {
                loading.setVisibility(View.GONE);
                VideoBeanBottom body = response.body();
                List<VideoBean> data = body.getData();
                ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
                if (page2==1){
                    VideoBean hotTitleBean = new VideoBean(ConstantUtils.FILM_LIBRARY, "我的片库");
                    multipleList.add(new PushMultipleItem(PushMultipleItem.title, hotTitleBean));
                }

                multipleItems.add(new PushMultipleItem(PushMultipleItem.item, "片库", data));
                mainAdapter.addData(multipleItems);
                if (page2 >= 10) {
                    mainAdapter.loadMoreEnd(false);
                } else {
                    page2++;
                    mainAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<VideoBeanBottom> response) {
                mainAdapter.loadMoreFail();
            }

        });
    }

    @NotNull
    private ArrayList<PushMultipleItem> getPushMultipleItems(GetTypeVodsBean body) {
        ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
        //遍历Map
        Map<String, ArrayList<VideoBean>> vods = body.getVods();
        Map<String, ArrayList<SubjectsBean>> beans = body.getSubjects();
        if (vods != null && beans != null) {
            for (String key : vods.keySet()) {
                ArrayList<VideoBean> videoBeans = vods.get(key);
                ArrayList<SubjectsBean> zhuanTiBannerBeans = beans.get(key);
                if (videoBeans != null && videoBeans.size() > 0) {
                    VideoBean bean = new VideoBean();
                    bean.setVod_name(ListSharedPreferences.getTypeName(Integer.parseInt(key)));
                    bean.setVod_id(Integer.parseInt(key));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.title, bean));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.banner, zhuanTiBannerBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.item, key, videoBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.changer, key, null));
                }
            }
        }
        return multipleItems;
    }
    }

老版核心代码——请使用对比软件,观察两个的不同:

public class ChildRecommendFragment  {

    @BindView(R.id.sl_Push)
    SwipeRefreshLayout sl_Push;

    @BindView(R.id.rv_pu_bu)
    RecyclerView rv_pu_bu;


    @BindView(R.id.loading)
    View loading;


    @BindView(R.id.load_err)
    View load_err;


    /**
     * 上拉加载页数
     */
    public int pagePullRefresh = 1;
    public int page = 1;
    public int page2 = 1;
    private RecommendAdapter mainAdapter;
    private RecommendAdapter bottomAdapter;
    private ArrayList<PushMultipleItem> multipleList = new ArrayList<>();
    private ArrayList<VideoBean> bottomData = new ArrayList<>();
  

    @Override
    protected void initView() {
        View bannerAdLayout = View.inflate(getContext(), R.layout.item_push_head_child, null);
        initBanner(bannerAdLayout);
        adImage = bannerAdLayout.findViewById(R.id.adImage);
        View head_big_recommend = View.inflate(getContext(), R.layout.head_big_recommend, null);
        RecyclerView rv_child_Push = head_big_recommend.findViewById(R.id.rv_child_Push);
        LinearLayoutManager manager = new LinearLayoutManager(mActivity);
        rv_child_Push.setLayoutManager(manager);

        mainAdapter = new RecommendAdapter(null);
        rv_child_Push.setAdapter(mainAdapter);

        LinearLayoutManager manager2 = new LinearLayoutManager(mActivity);
        rv_pu_bu.setLayoutManager(manager2);
        bottomAdapter = new RecommendAdapter(null);
        bottomAdapter.addHeaderView(head_big_recommend);
        rv_pu_bu.setAdapter(bottomAdapter);

        mainAdapter.addHeaderView(bannerAdLayout);
        pianKuHeader = View.inflate(getContext(), R.layout.header_title, null);
        mainAdapter.addFooterView(pianKuHeader, ConstantUtils.getSpanCount());


      
        //上拉加载
        mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                httpPager();
            }
        }, rv_child_Push);
        bottomAdapter.setLoadMoreView(new LoadingAddDataView());
        bottomAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                JumpUtils.jumpToPlayerAct(bottomData.get(position).getVod_id());
            }
        });
        bottomAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                httpPager2();
            }
        }, rv_pu_bu);

        sl_Push.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                pagePullRefresh = getRandomPageRefresh();
                page = 1;
                httpData();
            }
        });

        load_err.setOnClickListener(view -> {
            loading.setVisibility(View.VISIBLE);
            load_err.setVisibility(View.GONE);
            page = 1;
            httpData();
        });


    }

  
   

    @Override
    protected void initData() {
        loading.setVisibility(View.VISIBLE);
        httpData();
        page2 = 1;
        httpPager2();
    }

  

    /**
     * 请求数据集合
     */
    private void httpData() {

        String url = ConstantUtils.getUrlConstant().video_type
                + "?type_id=" + getArguments().get("id")
                + "&version=" + AppUtils.getAppVersionCode()
                + "&page=" + pagePullRefresh
                + "&mobiletype=1";

        OkGoUtils.getRequest(url, new JsonCallBack<GetTypeDetailBean>(GetTypeDetailBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeDetailBean, ? extends Request> request) {

            }

            @Override
            public void onSuccess(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                load_err.setVisibility(View.GONE);
                clearList();
                sl_Push.setRefreshing(false);
                GetTypeDetailBean body = response.body();
                multipleList = bornMultipleList(body);
                mainAdapter.setNewData(multipleList);

            }

            @Override
            public void onError(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                sl_Push.setRefreshing(false);
                ToastUtils.showShort("连接服务器失败");
                if (mainAdapter.getData().size() == 0) {
                    load_err.setVisibility(View.VISIBLE);
                }


            }

         
        });
    }


  

    private String getHotVideoNewUrl(String id) {
        return ConstantUtils.getUrlConstant().gethotvodnew
                + "?type_id=" + id
                + "&page=" + MyAppUtils.getRandomPage();
    }


    private ArrayList<PushMultipleItem> bornMultipleList(GetTypeDetailBean body) {
        ArrayList<PushMultipleItem> multipleList = new ArrayList<>();
        GetTypeDetailBean.RenhotBean renhot = body.getRenhot();
        VideoBean recentTitleBean = new VideoBean(ConstantUtils.RECENT_ID, ConstantUtils.RECENT_VALUE);
        VideoBean hotTitleBean = new VideoBean(ConstantUtils.HITS_ID, ConstantUtils.HITS_VALUE);
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, recentTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.RECENT_KEY, renhot.getRecent()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.RECENT_KEY, null));
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, hotTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.HITS_KEY, renhot.getHits()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.HITS_KEY, null));

        return multipleList;
    }

 

    private void clearList() {
        if (multipleList != null && multipleList.size() > 0) {
            multipleList.clear();
        }
    }


    /**
     * 分页请求
     */
    private void httpPager() {
        OkGoUtils.getRequest(getUrl(), new JsonCallBack<GetTypeVodsBean>(GetTypeVodsBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeVodsBean, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<GetTypeVodsBean> response) {

                GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page >= body.getLast_page()) {
                    mainAdapter.loadMoreEnd(true);
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<GetTypeVodsBean> response) {
                mainAdapter.loadMoreFail();
            }          
        });
    }

    @NotNull
    private String getUrl() {
        return ConstantUtils.getUrlConstant().getypevods
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page;
    }

    private void httpPager2() {
        String url = ConstantUtils.getUrlConstant().getrecentvod
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page2;

        OkGoUtils.getRequest(url, new JsonCallBack<VideoBeanBottom>(VideoBeanBottom.class, mActivity) {
            @Override
            public void onStart(Request<VideoBeanBottom, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<VideoBeanBottom> response) {
                if (pianKuHeader != null) {
                    pianKuHeader.setVisibility(View.VISIBLE);
                }
                loading.setVisibility(View.GONE);
                VideoBeanBottom body = response.body();
                List<VideoBean> data = body.getData();
                ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
                multipleItems.add(new PushMultipleItem(PushMultipleItem.item, "片库", data));
                bottomAdapter.addData(multipleItems);
                if (page2 >= 10) {
                    bottomAdapter.loadMoreEnd(false);
                } else {
                    page2++;
                    bottomAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<VideoBeanBottom> response) {
                bottomAdapter.loadMoreFail();
            }
        });
    }

    @NotNull
    private ArrayList<PushMultipleItem> getPushMultipleItems(GetTypeVodsBean body) {
        ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
        //遍历Map
        Map<String, ArrayList<VideoBean>> vods = body.getVods();
        Map<String, ArrayList<SubjectsBean>> beans = body.getSubjects();
        if (vods != null && beans != null) {
            for (String key : vods.keySet()) {
                ArrayList<VideoBean> videoBeans = vods.get(key);
                ArrayList<SubjectsBean> zhuanTiBannerBeans = beans.get(key);
                if (videoBeans != null && videoBeans.size() > 0) {
                    VideoBean bean = new VideoBean();
                    bean.setVod_name(ListSharedPreferences.getTypeName(Integer.parseInt(key)));
                    bean.setVod_id(Integer.parseInt(key));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.title, bean));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.banner, zhuanTiBannerBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.item, key, videoBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.changer, key, null));
                }
            }
        }
        return multipleItems;
    }


}

对比效果如图:

下拉刷新部分.png
第一个加载到底的是数据衔接部分 统一Adapter后,将第二个adapter换成第一个adapter

大概这也是我能想到的最好的办法了——核心代码用对比软件对比

参考链接:https://www.jianshu.com/p/1add7d5a4ec4
https://www.jianshu.com/p/34d2c5cdb3fb

上一篇下一篇

猜你喜欢

热点阅读