zoukankan      html  css  js  c++  java
  • Android中RecyclerView嵌套RecyclerView或嵌套ListView

     

    效果图:

    RecyclerView嵌套RecyclerView

    RecyclerView嵌套ListView

    原理

    RecyclerView嵌套RecyclerView的条目,项目中可能会经常有这样的需求,但是我们将子条目设置为RecyclerView之后,却显示不出来。自己试了很久,终于找到了原因:必须先设置子RecylcerView的高度。你要花精力确定出子RecyclerView里面条目的高度,然后从而确定子RecyclerView的高度,设置给子RecylcerView,这样做RecyclerView就可以正确显示出子ReclyclerView。

    代码

    首页布局就是一个竖直排列的RecyclerView

    1.  
      <?xml version="1.0" encoding="utf-8"?>
    2.  
      <android.support.v7.widget.RecyclerView
    3.  
      xmlns:android="http://schemas.android.com/apk/res/android"
    4.  
      android:id="@+id/recylcerview"
    5.  
      android:layout_width="match_parent"
    6.  
      android:layout_height="match_parent"/>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接下来在MainActivity对该布局进行初始化,然后制造一些假数据

    1.  
      protected void onCreate(Bundle savedInstanceState) {
    2.  
      super.onCreate(savedInstanceState);
    3.  
      setContentView(R.layout.activity_main);
    4.  
      basicParamInit();
    5.  
      initData();
    6.  
      initRecyclerView();
    7.  
      }
    8.  
       
    9.  
       
    10.  
       
    11.  
      private void basicParamInit() {
    12.  
      DisplayMetrics metric = new DisplayMetrics();
    13.  
      getWindowManager().getDefaultDisplay().getMetrics(metric);
    14.  
       
    15.  
      screenWidth = metric.widthPixels;
    16.  
       
    17.  
      }
    18.  
      private void initData() {
    19.  
      data = new DataInfor();
    20.  
      ArrayList<Integer> resourceList =new ArrayList<>();
    21.  
       
    22.  
      resourceList.add(R.drawable.aaa);
    23.  
      resourceList.add(R.mipmap.ic_launcher);
    24.  
      resourceList.add(R.drawable.aaa);
    25.  
      resourceList.add(R.mipmap.ic_launcher);
    26.  
      resourceList.add(R.drawable.aaa);
    27.  
      resourceList.add(R.mipmap.ic_launcher);
    28.  
      resourceList.add(R.drawable.aaa);
    29.  
      resourceList.add(R.mipmap.ic_launcher);
    30.  
       
    31.  
      data.gridData = data.horizontalData = data.verticalData = resourceList;
    32.  
       
    33.  
      }
    34.  
       
    35.  
      private void initRecyclerView() {
    36.  
      recylcerview = (RecyclerView) findViewById(R.id.recylcerview);
    37.  
       
    38.  
      recylcerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL,false));
    39.  
       
    40.  
      recylcerview.setBackgroundResource(R.color.c_e0e0e2);
    41.  
       
    42.  
      recylcerview.setAdapter(new RecyclerViewAdapter());
    43.  
      }

    接下来看看RecyclerView的Adapter:

    1.  
      private class RecyclerViewAdapter extends RecyclerView.Adapter<BaseHolder>{
    2.  
      private final int HORIZONTAL_VIEW = 1000;
    3.  
      private final int VERTICAL_VIEW = 1001;
    4.  
      private final int GRID_VIEW = 1002;
    5.  
       
    6.  
      @Override
    7.  
      public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    8.  
      switch (viewType){
    9.  
      case HORIZONTAL_VIEW:
    10.  
      return new HorizontalViewHolder(R.layout.item_recyclerview,parent,viewType);
    11.  
      case GRID_VIEW:
    12.  
      return new GridViewHolder(R.layout.item_recyclerview,parent,viewType);
    13.  
      case VERTICAL_VIEW:
    14.  
      return new ItemViewHolder(R.layout.item_x2_imageview,parent,viewType);
    15.  
      }
    16.  
      return null;
    17.  
      }
    18.  
       
    19.  
      @Override
    20.  
      public void onBindViewHolder(BaseHolder holder, int position) {
    21.  
      if(holder instanceof HorizontalViewHolder){
    22.  
      holder.refreshData(data.horizontalData,position);
    23.  
      }else if(holder instanceof GridViewHolder){
    24.  
      holder.refreshData(data.gridData,position);
    25.  
      }else if(holder instanceof ItemViewHolder){
    26.  
      holder.refreshData(data.verticalData.get(position - 2),position - 2);
    27.  
      }
    28.  
       
    29.  
      }
    30.  
       
    31.  
      @Override
    32.  
      public int getItemCount() {
    33.  
      return 2 + data.verticalData.size();
    34.  
      }
    35.  
       
    36.  
      @Override
    37.  
      public int getItemViewType(int position) {
    38.  
      if(position == 0) return HORIZONTAL_VIEW;
    39.  
      if(position == 1) return GRID_VIEW;
    40.  
      return VERTICAL_VIEW;
    41.  
      }
    42.  
      }

    可以看出,我们一共有三种条目类型,第一种是水平滑动的子RecyclerView,第二种是GridView形的子RecyclerView,第三种就是正常的子条目,根据viewType来返回不同的ViewHolder,到这里应该都没什么问题。

    接下来就是各个类型的ViewHolder了,在Holder当中,我们要计算条目的高度然后设置给子RecyclerView

    1.  
      private class HorizontalViewHolder extends BaseHolder<List<Integer>>{
    2.  
      private RecyclerView hor_recyclerview;
    3.  
       
    4.  
      private List<Integer> data;
    5.  
       
    6.  
      public HorizontalViewHolder(int viewId, ViewGroup parent, int viewType) {
    7.  
      super(viewId, parent, viewType);
    8.  
      hor_recyclerview = (RecyclerView) itemView.findViewById(R.id.item_recyclerview);
    9.  
      }
    10.  
       
    11.  
      @Override
    12.  
      public void refreshData(List<Integer> data, int position) {
    13.  
      this.data = data;
    14.  
      ViewGroup.LayoutParams layoutParams = hor_recyclerview.getLayoutParams();
    15.  
      //高度等于=条目的高度+ 10dp的间距 + 10dp(为了让条目居中)
    16.  
      layoutParams.height = screenWidth/3 + dip2px(20);
    17.  
      hor_recyclerview.setLayoutParams(layoutParams);
    18.  
      hor_recyclerview.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL,false));
    19.  
      hor_recyclerview.setBackgroundResource(R.color.colorAccent);
    20.  
      hor_recyclerview.setAdapter(new HorizontalAdapter());
    21.  
      }
    22.  
       
    23.  
      private class HorizontalAdapter extends RecyclerView.Adapter<BaseHolder>{
    24.  
       
    25.  
      @Override
    26.  
      public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    27.  
      return new ItemViewHolder(R.layout.item_x2_imageview,parent,viewType);
    28.  
      }
    29.  
       
    30.  
      @Override
    31.  
      public void onBindViewHolder(BaseHolder holder, int position) {
    32.  
      holder.refreshData(data.get(position),position);
    33.  
      }
    34.  
       
    35.  
      @Override
    36.  
      public int getItemCount() {
    37.  
      return data.size();
    38.  
      }
    39.  
      }
    40.  
      }

    水平的子RecyclerView的高度还是比较容易计算的,毕竟只有一行,高度相对来说是固定的。但是像GridView的高度是动态的,根据条目数量的不同,可能会有多行,所以我们需要先计算行数,然后每行的高度*行数才是子RecyclerView的高度

    1.  
      private class GridViewHolder extends BaseHolder<List<Integer>>{
    2.  
       
    3.  
      private RecyclerView item_recyclerview;
    4.  
       
    5.  
      private final int ONE_LINE_SHOW_NUMBER = 3;
    6.  
       
    7.  
      private List<Integer> data;
    8.  
       
    9.  
      public GridViewHolder(int viewId, ViewGroup parent, int viewType) {
    10.  
      super(viewId, parent, viewType);
    11.  
      item_recyclerview = (RecyclerView) itemView.findViewById(R.id.item_recyclerview);
    12.  
       
    13.  
      }
    14.  
       
    15.  
      @Override
    16.  
      public void refreshData(List<Integer> data, int position) {
    17.  
      super.refreshData(data, position);
    18.  
      this.data = data;
    19.  
      //每行显示3个,水平显示
    20.  
      item_recyclerview.setLayoutManager(new GridLayoutManager(MainActivity.this,ONE_LINE_SHOW_NUMBER,LinearLayoutManager.HORIZONTAL,false));
    21.  
       
    22.  
      ViewGroup.LayoutParams layoutParams = item_recyclerview.getLayoutParams();
    23.  
      //计算行数
    24.  
      int lineNumber = data.size()%ONE_LINE_SHOW_NUMBER==0? data.size()/ONE_LINE_SHOW_NUMBER:data.size()/ONE_LINE_SHOW_NUMBER +1;
    25.  
      //计算高度=行数*每行的高度 +(行数-1)*10dp的margin + 10dp(为了居中)
    26.  
      //因为每行显示3个条目,为了保持正方形,那么高度应该是也是宽度/3
    27.  
      //高度的计算需要自己好好理解,否则会产生嵌套recyclerView可以滑动的现象
    28.  
      layoutParams.height = lineNumber *(screenWidth/3) + (lineNumber-1)*dip2px(10) + dip2px(10);
    29.  
       
    30.  
      item_recyclerview.setLayoutParams(layoutParams);
    31.  
       
    32.  
      item_recyclerview.setBackgroundResource(R.color.colorPrimary);
    33.  
       
    34.  
      item_recyclerview.setAdapter(new GridAdapter());
    35.  
      }
    36.  
       
    37.  
       
    38.  
      private class GridAdapter extends RecyclerView.Adapter<BaseHolder>{
    39.  
       
    40.  
      @Override
    41.  
      public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    42.  
      return new ItemViewHolder(R.layout.item_x2_imageview,parent,viewType);
    43.  
      }
    44.  
       
    45.  
      @Override
    46.  
      public void onBindViewHolder(BaseHolder holder, int position) {
    47.  
      holder.refreshData(data.get(position),position);
    48.  
      }
    49.  
       
    50.  
      @Override
    51.  
      public int getItemCount() {
    52.  
      return data.size();
    53.  
      }
    54.  
      }
    55.  
       
    56.  
       
    57.  
      }

    其他代码我就不贴了,想要看源码的可以直接下载: 
    https://github.com/z593492734/nesting-recylcerview

    总体来说,RecyclerView嵌套RecyclerView是很简单的,而且也相当好用,希望这个demo可以给大家一些灵感。

    有任何问题都可以联系我:mengyuanzz@126.com

    下面是我修改后的例子:

    效果图:

    源码下载:

    http://download.csdn.net/detail/zhaihaohao1/9571152

    转载地址:

    http://blog.csdn.net/z593492734/article/details/51492472

  • 相关阅读:
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    面向对象
    三种循环结构语句
    JAVA复习题(一)基础知识
    JVM快速入门(上)
    count(*) 优化
    .jquery中$.get()提交和$.post()提交有区别吗?
    window.onload()函数和jQuery中的document.ready()有什么区别?
    假设有一个文本框要求输入10个字符的邮政编码,对于该文本框应该怎样划分等价类?
    软件测试项目从什么时候开始,?为什么?
  • 原文地址:https://www.cnblogs.com/xgjblog/p/14081763.html
Copyright © 2011-2022 走看看