安卓开发多选列表和回显已选择内容

news2024/11/27 9:39:01

问题背景

安卓日常开发和学习过程中,经常会碰到需要多选列表和显示已选择内容的场景,本文将介绍安卓实现多选列表和回显已选择内容的一种方案。

问题分析

话不多说,先上效果:
在这里插入图片描述

思路分析:
一个纵向列表显示待选择内容,一个横向列表用来显示已选择内容,点击待选列表和已选择列表的item都可以更新页面内容。

问题解决

话不多说,直接上代码。
(1)页面布局文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MultiChooseActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:textSize="18sp"
            android:text="已选择:"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/chosedList"
            android:layout_gravity="center_vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    <View
        android:layout_marginTop="3dp"
        android:layout_marginBottom="3dp"
        android:layout_width="match_parent"
        android:background="@color/black"
        android:layout_height="1dp"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/choicesList"
        android:layout_width="150dp"
        android:layout_height="wrap_content"/>
</LinearLayout>

(2)activity代码如下:

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

import android.os.Bundle;

import com.baorant.multichoosecomponent.adapter.Callback;
import com.baorant.multichoosecomponent.adapter.ChoosedAdapter;
import com.baorant.multichoosecomponent.adapter.MultiChooseAdapter;
import com.baorant.multichoosecomponent.databinding.ActivityMultiChooseBinding;
import com.baorant.multichoosecomponent.entity.ChoiceBean;

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

public class MultiChooseActivity extends AppCompatActivity {
    ActivityMultiChooseBinding binding;
    MultiChooseAdapter multiChooseAdapter;
    ChoosedAdapter choosedAdapter;

    /**
     * 所有选项
     */
    List<ChoiceBean> choiceBeans = new ArrayList<>();
    /**
     * 已选择列表
     */
    List<ChoiceBean> choseBeans = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initView();

        initData();
    }

    private void initView() {
        binding = ActivityMultiChooseBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        binding.choicesList.setLayoutManager(linearLayoutManager);
        multiChooseAdapter = new MultiChooseAdapter(this, choiceBeans, new Callback() {
            @Override
            public void callback(ChoiceBean data) {
                if (choiceBeans == null || choosedAdapter == null) {
                    return;
                }
                if (data.isBtnStatus()) {
                    choseBeans.add(data);
                } else {
                    choseBeans.remove(data);
                }
                choosedAdapter.notifyDataSetChanged();
            }
        });
        binding.choicesList.setAdapter(multiChooseAdapter);

        LinearLayoutManager linearLayoutManager1 = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
        binding.chosedList.setLayoutManager(linearLayoutManager1);
        choosedAdapter = new ChoosedAdapter(this, choseBeans, new Callback() {
            @Override
            public void callback(ChoiceBean data) {
                for (ChoiceBean choiceBean : choiceBeans) {
                    if (choiceBean.getTitle().equals(data.getTitle())) {
                        choiceBean.setBtnStatus(false);
                        break;
                    }
                }
                multiChooseAdapter.notifyDataSetChanged();
            }
        });
        binding.chosedList.setAdapter(choosedAdapter);
    }

    private void initData() {
        for(int i = 0; i < 10; i++) {
            choiceBeans.add(new ChoiceBean("第" + i + "个选项"));
        }
        multiChooseAdapter.notifyDataSetChanged();
    }
}

(3)待选择列表对应adapter,代码如下:

import android.content.Context;
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 com.baorant.multichoosecomponent.R;
import com.baorant.multichoosecomponent.entity.ChoiceBean;

import java.util.List;

/**
 * 多选adapter
 */
public class MultiChooseAdapter extends RecyclerView.Adapter<MultiChooseAdapter.ListViewHolder> {

    /**
     * 数据源
     */
    private List<ChoiceBean> dataList;
    private Context context;
    private Callback callback;

    public MultiChooseAdapter(Context context, List<ChoiceBean> dataList) {
        this.context = context;
        this.dataList = dataList;
    }

    public MultiChooseAdapter(Context context, List<ChoiceBean> dataList, Callback callback) {
        this.context = context;
        this.dataList = dataList;
        this.callback = callback;
    }

    @NonNull
    @Override
    public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = View.inflate(context, R.layout.item_mulit_choose, null);
        return new ListViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ListViewHolder holder, int position) {
        holder.tvTitle.setText(dataList.get(position).getTitle());
        if (dataList.get(position).isBtnStatus()) {
            holder.ivChoose.setImageResource(R.drawable.choose);
        } else {
            holder.ivChoose.setImageResource(R.drawable.not_choose);
        }
        holder.ivChoose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 把选中状态存到数据源类
                ChoiceBean data = dataList.get(position);
                // 取反状态值,赋值
                data.setBtnStatus(!data.isBtnStatus());
                // 刷新当前item
                notifyItemChanged(position);
                if (callback != null) {
                    callback.callback(data);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return (dataList == null) ? 0 : dataList.size();
    }

    public class ListViewHolder extends RecyclerView.ViewHolder {
        public TextView tvTitle;
        public ImageView ivChoose;

        public ListViewHolder(@NonNull View itemView) {
            super(itemView);
            tvTitle = itemView.findViewById(R.id.title);
            ivChoose = itemView.findViewById(R.id.status);
        }
    }

}

(4)已选择列表对应的adapter,代码如下:

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

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

import com.baorant.multichoosecomponent.R;
import com.baorant.multichoosecomponent.entity.ChoiceBean;

import java.util.List;

/**
 * 已选列表adapter
 */
public class ChoosedAdapter extends RecyclerView.Adapter<ChoosedAdapter.ListViewHolder> {

    /**
     * 数据源
     */
    private List<ChoiceBean> dataList;
    private Context context;
    private Callback callback;


    public ChoosedAdapter(Context context, List<ChoiceBean> dataList) {
        this.context = context;
        this.dataList = dataList;
    }

    public ChoosedAdapter(Context context, List<ChoiceBean> dataList, Callback callback) {
        this.context = context;
        this.dataList = dataList;
        this.callback = callback;
    }

    @NonNull
    @Override
    public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = View.inflate(context, R.layout.item_choosed, null);
        return new ListViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ListViewHolder holder, int position) {
        holder.tvTitle.setText(dataList.get(position).getTitle());
        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (callback != null) {
                    callback.callback(dataList.get(position));
                }

                dataList.remove(position);
                notifyDataSetChanged();
            }
        });
    }

    @Override
    public int getItemCount() {
        return (dataList == null) ? 0 : dataList.size();
    }

    public class ListViewHolder extends RecyclerView.ViewHolder {
        public TextView tvTitle;
        public ImageView delete;

        public ListViewHolder(@NonNull View itemView) {
            super(itemView);
            tvTitle = itemView.findViewById(R.id.title);
            delete = itemView.findViewById(R.id.delete);
        }
    }

}

(5)item_choosed.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MultiChooseActivity">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        tools:text="标题" />

    <ImageView
        android:id="@+id/delete"
        android:layout_toEndOf="@id/title"
        android:src="@drawable/delete"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:layout_centerVertical="true"/>
</RelativeLayout>

(6)item_mulit_choose.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="50dp"
    android:layout_height="20dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MultiChooseActivity">

    <TextView
        android:id="@+id/title"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        tools:text="标题" />

    <ImageView
        android:id="@+id/status"
        android:layout_alignParentEnd="true"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_centerVertical="true"
        tools:src="@drawable/choose"/>
</RelativeLayout>

(7)选项实体类,代码如下:

/**
 * 选项实体类
 */
public class ChoiceBean {
    private String title;
    // false代表未选中,true 选中
    private boolean btnStatus = false;

    public ChoiceBean(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

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

    public boolean isBtnStatus() {
        return btnStatus;
    }

    public void setBtnStatus(boolean btnStatus) {
        this.btnStatus = btnStatus;
    }
}


问题总结

本文介绍了安卓实现多选列表和回显已选择内容的一种方案,有兴趣的同学可以进一步深入研究。

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

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

相关文章

多线程基础(二)CAS无锁优化/自旋锁/乐观锁、ABA问题

CAS &#xff08;Compare And Set&#xff09;比较并替换 上篇文章的锁问题解决&#xff0c;可以使用更高效的方法&#xff0c;使用AtomXXX类&#xff0c;AtomXXX类本身方法都是原子性的&#xff0c;但不能保证多个方法连续调用是原于性的。 import java.util.ArrayList; imp…

chatgpt赋能Python-pythoncd

Python介绍 Python是一种流行的高级编程语言&#xff0c;由Guido van Rossum于1989年开发。Python的设计目标是简单易学、易于阅读和编写&#xff0c;同时也是一种高效的语言&#xff0c;能够处理各种不同的任务。Python在Web开发、数据分析、人工智能和科学计算等领域得到广泛…

chatgpt赋能Python-pythoncalendar

PythonCalendar&#xff1a;Python中优秀的日期处理库 作为一门快速发展的编程语言&#xff0c;Python提供了许多优秀的库和工具&#xff0c;用于方便程序员进行各种各样的操作和处理。其中&#xff0c;日期处理是一个必不可少的模块。PythonCalendar库就是Python中优秀的日期…

ChatGPT 的 AskYourPDF 插件所需链接如何获取?

一、背景 目前 ChatGPT 主要有两款 PDF 对话插件&#xff0c;一个是 AskYourPDF 一个是 ChatWithPDF&#xff08;需 ChatGPT Plus&#xff09;&#xff0c;他们都可以实现给一个公共的PDF 链接&#xff0c;然后进行持续对话&#xff0c;对读论文&#xff0c;阅读 PDF 格式的文…

Godot引擎 4.0 文档 - 循序渐进教程 - 创建实例

本文为Google Translate英译中结果&#xff0c;DrGraph在此基础上加了一些校正。英文原版页面&#xff1a; Creating instances — Godot Engine (stable) documentation in English 创建实例 在前面的部分中&#xff0c;我们看到场景是以树结构组织的节点集合&#xff0c;以…

【中间件】通过 docker-compose 快速部署 Kafka 保姆级教程

文章目录 一、概述二、前期准备1&#xff09;部署 docker2&#xff09;部署 docker-compose 三、创建网络四、安装 Zookeeper五、Kafka 编排部署1&#xff09;下载 Kafka2&#xff09;配置3&#xff09;启动脚本 bootstrap.sh4&#xff09;构建镜像 Dockerfile5&#xff09;编排…

【VMware】搭建个人服务器

文章目录 准备工作三种网络模式Bridged(桥接模式)定义设置 NAT(网络地址转换模式)定义设置 Host-Only(仅主机模式)定义设置 搭建服务器网络模式的选择在VMWare的网络编辑器中设置转发端口查看宿主机的ip地址使用ssh连接工具进行连接 Mac笔记本跑虚拟机总感觉别扭&#xff0c;通…

浅谈一下“近期强势”这个指数

最近的行情,如果不理解退潮,那就意味着完全不理解情绪周期,也自然对大周期和小周期的概念了,这样一来无论你嘴上套用什么分歧、一致、修复都是徒劳的。 我说过我定义的新周期开始到结束,为什么我能定义一个很长的大周期?因为我有办法去观察赚钱效应。 如果我们都能理解…

【分布式锁】Redisson分布式锁底层原理

文章目录 前言原理分析Redisson实现Redis分布式锁的底层原理1.加锁机制2.锁互斥机制3. watch dog自动延期机制4.可重入加锁机制5.释放锁机制6.上述Redis分布式锁的缺点 前言 现在最流行的redis分布式锁就是Redisson了&#xff0c;来看看它的底层原理就了解redis是如何使用分布…

真香,聊聊 RocketMQ 5.0 的 POP 消费模式!

大家好&#xff0c;我是君哥。 大家都知道&#xff0c;RocketMQ 消费模式有 PULL 模式和 PUSH 模式&#xff0c;不过本质上都是 PULL 模式&#xff0c;而在实际使用时&#xff0c;一般使用 PUSH 模式。 不过&#xff0c;RocketMQ 的 PUSH 模式有明显的不足&#xff0c;主要体…

Unity 过场工具(Cutscene)设计(四) ——组件化设计

Unity 过场工具(Cutscene)设计&#xff08;四&#xff09; ——组件化设计 写到这一篇文章前就开始在考虑如何才能说清楚自己的设计思路&#xff0c;因为后续涉及到编辑器和Runtime框架的实际设计和实现过程&#xff0c;两者之间是互相有设计因果关系的。为了阐述自己的核心设计…

从0.5开始开发一个导购网站

提醒&#xff1a;文中没有具体如何修改的代码&#xff0c;只是提供了修改的思路。 为什么是从0.5开始呢&#xff1f; 因为这里借助了一个大佬的开源项目Springboot项目仿天猫商城: Springboot项目仿天猫商城 前台jsp页面 大佬的代码简洁&#xff0c;没有什么多余的功能&…

系统调用与API

系统调用介绍 什么是系统调用 为了让应用程序有能力访问系统资源&#xff0c;也为了让程序借助操作系统做一些由操作系统支持的行为&#xff0c;每个操作系统都会提供一套接口&#xff0c;以供应用程序使用。系统调用涵盖的功能很广&#xff0c;有程序运行所必需的支持&#xf…

leetCode刷题记录2

文章目录 hot100题560. 和为 K 的子数组581. 最短无序连续子数组 ▲617. 合并二叉树 hot100题 560. 和为 K 的子数组 560. 和为 K 的子数组 先暴力&#xff0c;过了再说 public int subarraySum(int[] nums, int k) {int ans 0;for (int i 0; i < nums.length; i) {in…

保姆级教程Windows11下安装RocketMQ

一、RocketMQ介绍 RocketMQ 是阿里巴巴开源的分布式消息中间件。支持事务消息、顺序消息、批量消息、定时消息、消息回溯等。它里面有几个区别于标准消息中件间的概念&#xff0c;如Group、Topic、Queue等。系统组成则由Producer、Consumer、Broker、NameServer等。 二、Rock…

vector类详解【c++】

&#x1f600;博主主页 &#x1f600;博主码云 目录 &#x1f3c5;vector简介&#x1f3c5;vector使用&#x1f3c6;vector的定义&#x1f3c6;vector iterator 的使用&#x1f3c6;vector 空间函数&#x1f3c6;vector的扩容问题&#x1f3c6;vector 增删查改&#x1f3c6;vec…

Python tkintertools 模块介绍(新版)

&#x1f680;tkintertools&#x1f680; The tkintertools module is an auxiliary module of the tkinter module tkintertools 模块是 tkinter 模块的辅助模块 Installation/模块安装 Stable version/稳定版本 Version/版本 : 2.6.1Release Date/发布日期 : 2023/05/21 p…

Edge 浏览器:隐藏功能揭秘与高效插件推荐

文章目录 一、前言二、Edge 的各种奇淫巧计2.1 开启 Edge 分屏功能2.2 启动 Edge 浏览器后直接恢复上次关闭前的页面2.3 解决 Edge 浏览器无法同步账号内容2.4 开启垂直标签页&#xff08;推荐&#xff09;2.5 设置标签分组&#xff08;推荐&#xff09;2.6 设置标签睡眠时间&a…

网络管理 - 简单网络管理协议 SNMP

文章目录 1 概述1.1 结构1.2 操作 2 SNMP2.1 报文格式2.2 五大报文类型2.3 三大组件 3 扩展3.1 网工软考真题 1 概述 #mermaid-svg-xmaaQjpp1bT1axfw {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-xmaaQjpp1bT1axf…

实验篇(7.2) 01. 实验环境介绍 远程访问 ❀ Fortinet网络安全专家 NSE4

【简介】学习NSE4&#xff0c;如果只看文章而不动手做实验&#xff0c;就象耍流氓。为了有效的巩固学习到的内容&#xff0c;建议经常动手做实验。实验不怕出错&#xff0c;身经百战后&#xff0c;再在生产环境部署和配置FortiGate防火墙&#xff0c;就会做到胸有成竹。 虚拟实…