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

发布时间 - 2026-01-11 02:49:10    点击率:

很多时候会遇到一种需求,列表里面有列表,像这种需求之前一般都是用多个列表控件互相嵌套来实现,但是这样很容易出现一些问题,例如滚动冲突、数据显示不全、多余的逻辑处理等。后来发现,一个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  # 列表嵌套  # RecyclerView实现列表嵌套  # RecyclerView  # Android中RecyclerView实现多级折叠列表效果(二)  # Android中RecyclerView实现多级折叠列表效果(TreeRecyclerView)  # RecyclerView实现常见的列表菜单  # Android RecyclerView实现数据列表展示效果  # Android使用RecyclerView实现自定义列表、点击事件以及下拉刷新  # 使用RecyclerView实现水平列表  # Android列表RecyclerView排列布局  # RecyclerView优雅实现复杂列表布局  # 三种  # 数据处理  # 都是  # 涉及到  # 放在  # 第一个  # 多个  # 深坑  # 绑定  # 是一个  # 子类  # 把他  # 很容易  # 第二个  # 不了解  # 在后面  # 不能用  # 第三个  # 不全  # 所需要 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: lovemo网页版地址 lovemo官网手机登录  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  如何用5美元大硬盘VPS安全高效搭建个人网站?  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  如何在万网主机上快速搭建网站?  Laravel如何实现用户密码重置功能?(完整流程代码)  Bootstrap CSS布局之列表  浅谈redis在项目中的应用  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  C语言设计一个闪闪的圣诞树  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  如何在IIS中新建站点并配置端口与IP地址?  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  实例解析angularjs的filter过滤器  QQ浏览器网页版登录入口 个人中心在线进入  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  Android自定义控件实现温度旋转按钮效果  用yum安装MySQLdb模块的步骤方法  Swift开发中switch语句值绑定模式  如何快速搭建安全的FTP站点?  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】  网站制作软件免费下载安装,有哪些免费下载的软件网站?  高性价比服务器租赁——企业级配置与24小时运维服务  如何快速搭建支持数据库操作的智能建站平台?  高端云建站费用究竟需要多少预算?  七夕网站制作视频,七夕大促活动怎么报名?  Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】  Laravel模型事件有哪些_Laravel Model Event生命周期详解  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  非常酷的网站设计制作软件,酷培ai教育官方网站?  如何在建站之星网店版论坛获取技术支持?  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程  如何用wdcp快速搭建高效网站?  php打包exe后无法访问网络共享_共享权限设置方法【教程】  Laravel如何使用Collections进行数据处理?(实用方法示例)  香港服务器部署网站为何提示未备案?  Laravel如何使用Sanctum进行API认证?(SPA实战)  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  如何快速配置高效服务器建站软件?  如何快速生成凡客建站的专业级图册?  深圳网站制作培训,深圳哪些招聘网站比较好?  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  微信小程序 scroll-view组件实现列表页实例代码  JavaScript常见的五种数组去重的方式  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】