RecyclerView ViewType二级

news2024/12/29 8:54:27

实现效果描述:
1、点击recyclerview中item,列表下方出现其他样式的item,作为子item,如下所示
在这里插入图片描述

所需要的java文件和xml文件有:
在这里插入图片描述

1、创建FoldAdapteradapter, 在FoldAdapter中,定义两种不同的类型,分别对应父item和子item,对于不同布局的item,需要设置两种不同的viewHoder进行设置。
2、在onCreateViewHolder进行对于布局的绑定
3、在onBindViewHoder中进行数据的操作
4、在getItemViewType返回对应的类型
5、在getItemCount中返回对应的大小

FoldAdapter:

package com.example.expandtworecyclerviewdemo;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;
import java.util.PropertyResourceBundle;
import java.util.zip.Inflater;

public class FoldAdapteer extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int PARENT_TYPE = 0X0000;
    private static final int CHILD_TYPE = 0X0001;
    private Context mContext;
    private List<ITyple> dataList = new ArrayList<>();

    public FoldAdapteer(Context context){
        mContext = context;
    }

    public void setData(List<ITyple> iTyples){
        //对于list的数据不能简单的是等于的操作
        this.dataList.clear();
        this.dataList.addAll(iTyples);
        notifyDataSetChanged();
    }

    @Override
    public int getItemViewType(int position) {
        if (dataList.get(position).getTyple() == EType.PARENT_TYPE) {
            return PARENT_TYPE;
        }
        if (dataList.get(position).getTyple() == EType.CHILD_TYPE){
            return CHILD_TYPE;
        }
        return super.getItemViewType(position);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == PARENT_TYPE){
            View mView = LayoutInflater.from(mContext).inflate(R.layout.parent_layout, parent, false);
            return new ParentHoder(mView);
        }else if (viewType == CHILD_TYPE){
            View mView = LayoutInflater.from(mContext).inflate(R.layout.child_layout, parent, false);
            return new ChildHoder(mView);
        }

        return null;
    }

       @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
        if (holder instanceof ParentHoder){
            ParentHoder parentHoder = (ParentHoder)holder;
            final DateBean.ParentBean parentBean = (DateBean.ParentBean) dataList.get(position);
            parentHoder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.d("lucky", "onClick: " + parentBean);
                    if (parentBean.isExpand()){
                        closeParent(position, parentBean);
                        ((ParentHoder) holder).mImage.setImageResource(R.drawable.icon_parent_down);
                    }else {
                        openParent(position, parentBean);
                        ((ParentHoder) holder).mImage.setImageResource(R.drawable.icon_parent_right);
                    }
                    parentBean.setExpand(!parentBean.isExpand());
                }
            });
            DateBean.ParentBean bindata = (DateBean.ParentBean) dataList.get(position);
            ((ParentHoder) holder).mImage.setImageResource(R.drawable.icon_parent_down);
            ((ParentHoder) holder).text.setText(bindata.getTextParent());
        }else if (holder instanceof ChildHoder){
            DateBean.ChildBean childBean = (DateBean.ChildBean)dataList.get(position);
            ((ChildHoder) holder).text.setText(childBean.getTextChild());
        }

    }


    private void openParent(int position , DateBean.ParentBean parentBean) {
        Log.d("lucky", "openParent: "  + dataList.get(position));
      //  DateBean.ParentBean parentBean = (DateBean.ParentBean)dataList.get(position);
        List<DateBean.ChildBean> child = parentBean.getChildBeans();
        dataList.addAll(position+1, child);
  //      notifyDataSetChanged();
       notifyItemRangeInserted(position+1, child.size());
       notifyItemRangeChanged(position+1, child.size());
//     //   notifyItemChanged(position);
    }

    private void closeParent(int position, DateBean.ParentBean parentBean) {
        // = (DateBean.ParentBean)dataList.get(position);
        List<DateBean.ChildBean> child = parentBean.getChildBeans();

        dataList.removeAll(child);
        notifyItemRangeRemoved(0,child.size());
        notifyDataSetChanged();
    //   notifyItemRangeInserted(position+1, child.size());
   //     notifyItemRangeChanged(position+1, child.size());
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }
    private static class ParentHoder extends RecyclerView.ViewHolder {
        private TextView text;
        private ImageView mImage;
        public ParentHoder(@NonNull View itemView) {
            super(itemView);
            text = itemView.findViewById(R.id.parent_id);
            mImage = itemView.findViewById(R.id.paren_image);

        }
    }

    private static class ChildHoder extends RecyclerView.ViewHolder{
        private TextView text;
        public ChildHoder(@NonNull View itemView) {
            super(itemView);
            text = itemView.findViewById(R.id.child_id);
        }
    }
}

DataBean

package com.example.expandtworecyclerviewdemo;

import android.widget.TextView;

import java.util.List;

public class DateBean {

    private List<ParentBean> parentBean;

    public List<ParentBean> getParentBean() {
        return parentBean;
    }

    public void setParentBean(List<ParentBean> parentBean) {
        this.parentBean = parentBean;
    }

    public static class ParentBean implements ITyple {
        private List<ChildBean> childBeans;
        private boolean isExpand = false;
        private String textParent;

        public String getTextParent() {
            return textParent;
        }

        public void setTextParent(String textParent) {
            this.textParent = textParent;
        }

        public boolean isExpand() {
            return isExpand;
        }

        public void setExpand(boolean expand) {
            isExpand = expand;
        }

        public List<ChildBean> getChildBeans() {
            return childBeans;
        }

        public void setChildBeans(List<ChildBean> childBeans) {
            this.childBeans = childBeans;
        }

        @Override
        public EType getTyple() {
            return EType.PARENT_TYPE;
        }
    }

    public static class ChildBean implements ITyple{
        private String textChild;

        public String getTextChild() {
            return textChild;
        }

        public void setTextChild(String textChild) {
            this.textChild = textChild;
        }

        @Override
        public EType getTyple() {
            return EType.CHILD_TYPE;
        }
    }
}

接口的作用,是为了使得ParentBean和ChildBean实现接口,从而返回对应的类型,执行相关的操作。
在写代码过程中,有个点可能会比较疑问,为什么在adapter中有泛型为IType的集合?
因为这样的话,根据不同的类型执行后获取的数据,可通过强制装换获取存在的数据为身为子类的ParenBean和ChildBean。

接口IType

package com.example.expandtworecyclerviewdemo;

public interface ITyple {

    EType getTyple();
}

列举不同的数据,枚举是默认从0开始计数。

枚举EType

package com.example.expandtworecyclerviewdemo;

public enum EType {
    PARENT_TYPE,
    CHILD_TYPE
}

MainActivity

package com.example.expandtworecyclerviewdemo;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.widget.Adapter;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    List<ITyple> iTyples = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //绑定对应的layout文件
        this.setContentView(R.layout.activity_main);
        RecyclerView mRecyclerView = this.findViewById(R.id.recyclerview);
        //加载recycler中的布局,缺少会报错
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        FoldAdapteer recyclerAdapter = new FoldAdapteer(this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(recyclerAdapter);

			//数据的输入
      for (int i= 0; i< 10 ; i++){
            DateBean.ParentBean parentBean = new DateBean.ParentBean();
            List<DateBean.ChildBean> childBean = new ArrayList<>();
            parentBean.setTextParent(i + " -> parren ");
            for (int j =0 ; j< 10 ; j++){
                DateBean.ChildBean childBean1 = new DateBean.ChildBean();
                childBean1.setTextChild(j + "-> child");
                childBean.add(childBean1);
            }
            parentBean.setChildBeans(childBean);
            iTyples.add(parentBean);
        }

        //数据传送到FolderAdapter中
        recyclerAdapter.setData(iTyples);
    }
}

main_xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

parent_layout


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="#5FC0EC"
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <ImageView
        android:id="@+id/paren_image"
        android:layout_width="30dp"
        android:layout_height="12dp"
        android:layout_gravity="center"
       />
    <TextView
        android:id="@+id/parent_id"
        android:layout_width="match_parent"
        android:layout_height="30dp"
       />
</LinearLayout>


child_layout

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/child_id"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="#BA9CF0">
</TextView>

三级标题确实是一样的处理方式,就是在childData中再加一个list放数据,然后在adapter进行点击处理的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389102.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Allegro如何将Waived掉的DRC显示或隐藏操作指导

Allegro如何将Waived掉的DRC显示或隐藏操作指导 在用Allegro做PCB设计的时候,如果遇到正常的DRC,可以用Waive的命令将DRC不显示,如下图 当DRC被Waive掉的时候,如何将DRC再次显示出来。类似下图效果 具体操作如下 点击Display

linux下strace的使用

strace是一款用于跟踪Linux系统调用和信号的工具&#xff0c;可以帮助开发者排除程序运行时的问题。 具体来说&#xff0c;strace可以跟踪一个程序执行时所涉及到的系统调用&#xff0c;包括读写文件、网络通信、进程管理、内存管理等操作&#xff0c;通过分析程序运行过程中发…

JavaWeb--JSP案例

JSP案例8 案例8.1 环境准备8.1.1 创建工程8.1.2 创建包8.1.3 创建表8.1.4 创建实体类8.1.5 准备mybatis环境8.2 查询所有8.2.1 编写BrandMapper8.2.2 编写工具类8.2.3 编写BrandService8.2.4 编写Servlet8.2.5 编写brand.jsp页面8.2.6 测试8.3 添加8.3.1 编写BrandMapper方法8.…

ARM uboot 的移植0-从三星官方 uboot 开始移植的准备工作

一、移植前的准备工作 1、三星移植过的uboot源代码准备 (1) 三星对于 S5PV210 的官方开发板为 SMDKV210&#xff0c;对应的移植过的 uboot 是&#xff1a;三星官方为210移植过的uboot和kernel/android_uboot_smdkv210.tar.bz2。 (2) 这个源代码网上是下载不到的&#xff0c;…

Leetcode.2397 被列覆盖的最多行数

题目链接 Leetcode.2397 被列覆盖的最多行数 Rating &#xff1a; 1719 题目描述 给你一个下标从 0 开始的 m x n二进制矩阵 mat和一个整数 cols&#xff0c;表示你需要选出的列数。 如果一行中&#xff0c;所有的 1 都被你选中的列所覆盖&#xff0c;那么我们称这一行 被覆盖…

RabbitMQ的使用以及整合到SpringBoot中

RabbitMQ的使用以及整合到SpringBoot中 一、比较&#xff1a; (1)、传统请求服务器&#xff1a; (2)、通过MQ去操作数据库&#xff1a; 通过MQ去操作数据库&#xff0c;从而达到削峰的效果&#xff1b; 问题现象&#xff1a; (1)、海量数据&#xff1b; (2)、高并发&#…

Python如何获取弹幕?给你介绍两种方式

前言 弹幕可以给观众一种“实时互动”的错觉&#xff0c;虽然不同弹幕的发送时间有所区别&#xff0c;但是其只会在视频中特定的一个时间点出现&#xff0c;因此在相同时刻发送的弹幕基本上也具有相同的主题&#xff0c;在参与评论时就会有与其他观众同时评论的错觉。 在国内…

【SQLAlchemy】第二篇——连接失效及连接池

一、背景 为了节约资源&#xff0c;MySQL会对建立的连接进行监控&#xff0c;当某些连接处于不活跃状态的时间超过一个阈值时&#xff0c;则关闭它们。 用户可以执行show variables like %wait_timeout%;来查看这个阈值&#xff1a; 可以看到&#xff0c;在默认的情况下&…

Multi-modal Graph Contrastive Learning for Micro-video Recommendation

模型总览如下&#xff1a; 解决问题&#xff1a;同种重要性对待每种模态&#xff0c;可能使得得到的特征表示次优&#xff0c;例如过度强调学习到的表示中的特定模态。以MMGCN为例&#xff0c;下图为MMGCN模型总览。 如上图所示MMGCN在每种模态上构建用户-物品二部图&#xff0…

【云原生】Gateway网关选型

网关一般分为流量网关和业务网关&#xff0c;流量网关负责接入所有的流量&#xff0c;并分发给不同的子系统&#xff0c;那在具体的业务接入之前&#xff0c;还有一层业务网关。流量网关提供全局性的、与后端业务应用无关的策略&#xff0c;例如 HTTPS证书卸载、Web防火墙、全局…

[vue]vue3.x 组合式API不同写法

[vue]vue3.x 组合式API不同写法改进后组合API实际实际使用中的疑问组件名称问题两种写法的优缺点对比优点缺点组合式API&#xff0c;采用了更加灵活的方式,官网推荐的语法糖&#xff0c;但仅限于比较简单的单文件&#xff0c;作为尝试 改进后组合API实际实际使用中的疑问 改进…

4-2 Linux进程和内存概念

文章目录前言进程状态进程优先级内存模型进程内存关系前言 进程是一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源。一般来说&#xff0c;Linux系统会在进程之间共享程序代码和系统函数库&#xff0c;所以在任何时刻内存中都只有代码的一份拷贝。 进程状态…

36_2 On Chip Bus —— AXI总线介绍

目录 1.AXI总线介绍&#xff08;读2写3&#xff09; 1.1流量控制 1.2 AXI signals 信号线 1.3重点信号线的介绍 1.4原子操作——让读改写一套操作 永远是一个master对一个slave 1.5AXI BURST Boundary——一个burst不能跨4k boundary&#xff0c;master要保证 1.6读/写通…

k8s中的PV和PVS

前言&#xff1a;容器磁盘上的文件的生命周期是短暂的&#xff0c;这就使得在容器中运行重要应用时会出现一些问题。首先&#xff0c;当容器崩溃时&#xff0c;kubelet 会重启它&#xff0c;但是容器中的文件将丢失——容器以干净的状态&#xff08;镜像最初的状态&#xff09;…

Python 算法交易实验51 Step2 Signals 信号生成

说明 不可不读书 先从经典的一些超简单信号开始 使用移动平均指标SMA(算术&#xff09; 给出了信号的产生方法&#xff0c;还有一些测算结果&#xff0c;反正看起来都是盈利的 首先使用离线方法实验一组结果&#xff0c;然后就使用ADBS来进行类似的处理。 内容 1 原理分析…

【python中的列表和元组】

文章目录前言一、列表及其使用1.列表的特点2. 列表的使用方法二、元组及其特点1.元组的类型是tuple1.元组的查找操作2. 计算元组某个元素出现的次数3.统计元组内元素的个数总结前言 本文着重介绍python中的列表和元组以及列表和元组之间的区别 一、列表及其使用 1.列表的特点…

JavaSE学习进阶day2_02 抽象类和接口

第四章 抽象类 4.1 概述 4.1.1 抽象类引入 先看一张图&#xff1a; 这张图时之前学习继承时用的&#xff0c;但是现在有一个疑问&#xff0c;吃饭这个行为猫和狗都有&#xff0c;但是它们吃的东西却又不同&#xff0c;这个时候我们不能确定父类吃饭这个方法到底该写什么&…

数据库分库分表策略

一、MySQL扩展具体的实现方式 随着业务规模的不断扩大&#xff0c;需要选择合适的方案去应对数据规模的增长&#xff0c;以应对逐渐增长的访问压力和数据量。 关于数据库的扩展主要包括&#xff1a;业务拆分、主从复制&#xff0c;数据库分库与分表。这篇文章主要讲述数据库分库…

03-SQLPlus的常用命令和使用

本章内容讲解SQLPlus的常用命令使用方法&#xff0c;参数的设置&#xff0c;帮助的使用&#xff0c;详细讲解如下&#xff1a; 登录SQL*Plus DOS方式登录SQL*Plus C:\>sqlplus 提示输入用户名、密码 C:\>sqlplus scott/tiger 连到默认数据库,注册表或环境变量中设 …

Blender——植物生长动画制作

效果图前言参考链接&#xff1a;https://www.bilibili.com/video/BV1aY411G7bk/?spm_id_from333.788.recommend_more_video.10&vd_source5212838c127b01db69dcc8b2d27ca517建议Blender的版本在3.0.0或以上。制作完成的植物生长动画blender文件下载&#xff1a;https://dow…