Android单个RecyclerView实现列表嵌套的效果

 更新时间:2017年08月16日 11:24:57   作者:WYiang   我要评论
本篇文章主要介绍了Android单个RecyclerView实现列表嵌套的效果,具有一定的参考价值,有兴趣的可以了解一下

很多时候会遇到一种需求,列表里面有列表,像这种需求之前一般都是用多个列表控件互相嵌套来实现,但是这样很容易出现一些问题,例如滚动冲突、数据显示不全、多余的逻辑处理等。后来发现,一个recyclerview就可以实现列表嵌套的效果,这里需要用到recyclerview的多布局功能。

效果图:


recyclerview的多布局涉及到的主要方法是getItemViewType,作用是设置每个item要显示的布局类型。之前不了解的时候,都是直接用数学逻辑直接去计算,多少个position后显示什么布局,这种方式适合在逻辑简单的时候,但是一旦逻辑稍微有点复杂就果断不能用,可能会自己埋下深坑不说,还不好维护,所以这边把布局类型放在数据对象中。

1. 定义多布局对象的基类:

public class BaseMulDataModel {
  protected int type;

  public int getType() {
    return type;
  }

  public void setType(int type) {
    this.type = type;
  }
}

type是该对象对应的布局类型。

2. recyclerview数据的显示放在ViewHolder中,定义Holder基类

public abstract class BaseMulViewHolder<T extends BaseMulDataModel> extends RecyclerView.ViewHolder {

  public BaseMulViewHolder(View itemView) {
    super(itemView);
  }

  protected abstract void bindData(T dataModel);

}

这里面多布局中可能涉及到的多个对象,所以基类中的对象类型使用泛型定义,必须是多布局对象基类的子类,这样在后面数据和控件绑定的时候比较方便。

3. 开始创建多布局适配器

public class MullayoutAdapter extends RecyclerView.Adapter<BaseMulViewHolder> {

  /**
   * 定义三种布局类型
   */
  public static final int TYPE_ONE = 1;
  public static final int TYPE_TWO = 2;
  public static final int TYPE_THREE = 3;

  /**
   * 数据集合
   */
  private List<BaseMulDataModel> mList;

  @Override
  public BaseMulViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    //根据不同的布局类型,设置创建相关的holder
    switch (viewType) {
      case TYPE_ONE:
        return new ViewHolderOne(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_holder1, parent, false));
      case TYPE_TWO:
        return new ViewHolderTwo(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_holder2, parent, false));
      case TYPE_THREE:
        return new ViewHolderThree(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_holder3, parent, false));
    }
    return null;
  }

  @Override
  public void onBindViewHolder(BaseMulViewHolder holder, int position) {
    //绑定数据
    holder.bindData(mList.get(position));
  }

  @Override
  public int getItemCount() {
    return mList.size();
  }

  @Override
  public int getItemViewType(int position) {
    return mList.get(position).getType();
  }

  /**
   * 设置数据
   *
   * @param list
   */
  public void setDatas(List<BaseMulDataModel> list) {
    mList = list;
    notifyDataSetChanged();
  }

  public List<BaseMulDataModel> getDatas() {
    return mList;
  }

  /**
   * 设置第一个布局的数据
   */
  class ViewHolderOne extends BaseMulViewHolder<OneModel> {
    TextView textView;

    public ViewHolderOne(View itemView) {
      super(itemView);
      textView = (TextView) itemView.findViewById(R.id.holder1_tv);
    }

    @Override
    protected void bindData(OneModel dataModel) {
      textView.setText(dataModel.getTitle());
    }
  }


  /**
   * 设置第二个布局的数据
   */
  class ViewHolderTwo extends BaseMulViewHolder<TwoModel> {
    ImageView imageView;

    public ViewHolderTwo(View itemView) {
      super(itemView);
      imageView = (ImageView) itemView.findViewById(R.id.holder2_iv);
    }

    @Override
    protected void bindData(TwoModel dataModel) {
      imageView.setImageResource(dataModel.getRes());
    }


  }

  /**
   * 设置第三个布局的数据
   */
  class ViewHolderThree extends BaseMulViewHolder<ThreeModel> {
    TextView textView;

    public ViewHolderThree(View itemView) {
      super(itemView);
      textView = (TextView) itemView.findViewById(R.id.holder3_tv);
    }

    @Override
    protected void bindData(ThreeModel dataModel) {
      textView.setText(dataModel.getNote());
    }


  }

}

首先这边涉及到布局类型:头部、内容列表、底部。定义三种类型

/**
* 定义三种布局类型
*/
public static final int TYPE_ONE = 1;
public static final int TYPE_TWO = 2;
public static final int TYPE_THREE = 3;

根据布局类型来创建对应的ViewHolder对象

  public BaseMulViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    //根据不同的布局类型,设置创建相关的holder
    switch (viewType) {
      case TYPE_ONE:
        return new ViewHolderOne(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_holder1, parent, false));
      case TYPE_TWO:
        return new ViewHolderTwo(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_holder2, parent, false));
      case TYPE_THREE:
        return new ViewHolderThree(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_holder3, parent, false));
    }
    return null;
  }

当然事先创建对应的Holder类:

  /**
   * 设置第一个布局的数据
   */
  class ViewHolderOne extends BaseMulViewHolder<OneModel> {
    TextView textView;

    public ViewHolderOne(View itemView) {
      super(itemView);
      textView = (TextView) itemView.findViewById(R.id.holder1_tv);
    }

    @Override
    protected void bindData(OneModel dataModel) {
      textView.setText(dataModel.getTitle());
    }
  }

这边把泛型对象擦除,使用具体对象OneModel来作为当前的数据对象。OneModel是BaseMulDataModel的基类。

OneModel的定义:

public class OneModel extends BaseMulDataModel {

  private String title;

  public OneModel(String title, int type) {
    this.title = title;
    this.type = type;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }
}

4. 进行数据处理

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    recycler.setLayoutManager(layoutManager);

    final MullayoutAdapter adapter = new MullayoutAdapter();
    recycler.setAdapter(adapter);

    //数据处理
    List<BaseMulDataModel> mList = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
      mList.add(new OneModel("头部" + i, MullayoutAdapter.TYPE_ONE));
      for (int j = 0; j < 3; j++) {
        mList.add(new TwoModel(R.mipmap.ic_launcher, MullayoutAdapter.TYPE_TWO));
      }
      mList.add(new ThreeModel("底部" + i, MullayoutAdapter.TYPE_THREE));
    }
    adapter.setDatas(mList);
  }
}

后台返回的数据一般不是我们想要的格式,所以自己进行数据的拆分处理,数据的处理方式很大程度上决定了代码编写的难易度。

这边的数据处理是把简单地需要显示的数据按顺序依次放入到数据集合list中,然后给每个对象设置type,定义它所需要的布局类型,数据的处理方式比较简单,但是能应付很多的场景。在购物车场景中,一般也是像示例一样,有头部、内容、底部。后台返回的数据可能是一个json对象包含了所有(头部、内容列表、底部),这边把他拆分成三部分,在依次放入集合中显示。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android实现桌面悬浮小火箭效果

    Android实现桌面悬浮小火箭效果

    这篇文章主要为大家详细介绍了Android实现桌面悬浮小火箭效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • Android BroadcastReceiver实现网络状态实时监听

    Android BroadcastReceiver实现网络状态实时监听

    这篇文章主要为大家详细介绍了Android BroadcastReceiver实现网络状态实时监听,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Android中TelephonyManager用法实例

    Android中TelephonyManager用法实例

    这篇文章主要介绍了Android中TelephonyManager用法,结合实例形式分析了TelephonyManager类的功能,使用技巧与相关注意事项,需要的朋友可以参考下
    2016-03-03
  • Kotlin中单利常用的五种写法

    Kotlin中单利常用的五种写法

    这篇文章主要给大家介绍了关于Kotlin中单利常用的五种写法,文中通过示例代码介绍的非常详细,对大家的学习合作工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-06-06
  • Android 自定义手势--输入法手势技术

    Android 自定义手势--输入法手势技术

    这篇文章主要介绍了Android 自定义手势--输入法手势技术的相关资料,需要的朋友可以参考下
    2016-10-10
  • android中暂停背景音乐

    android中暂停背景音乐

    本文给大家分享的是在Android中暂停背景音乐的方法的示例,以及度娘上其他网友的实现方法,感觉非常不错,这里全部推荐给大家,有需要的小伙伴可以参考下。
    2015-05-05
  • Android组件之DrawerLayout实现抽屉菜单

    Android组件之DrawerLayout实现抽屉菜单

    DrawerLayout组件同样是V4包中的组件,也是直接继承于ViewGroup类,所以这个类也是一个容器类。接下来通过本文给大家介绍Android组件之DrawerLayout实现抽屉菜单,感兴趣的朋友一起学习吧
    2016-02-02
  • Android开发之Activity全透明渐变切换方法

    Android开发之Activity全透明渐变切换方法

    下面小编就为大家分享一篇Android开发之Activity全透明渐变切换方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android编程实现随机生成颜色的方法示例

    Android编程实现随机生成颜色的方法示例

    这篇文章主要介绍了Android编程实现随机生成颜色的方法,结合实例形式分析了Android使用java Random类针对随机数及颜色值相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • App内切换语言详解

    App内切换语言详解

    本篇文章主要介绍了App内切换语言的方法。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04

最新评论