【Android】kotlin RecyclerView遍历json实现列表数据

news2024/12/26 12:01:30

需求

效果图如下 :
在这里插入图片描述
这个ui看起来简单, 其实要实现几个功能点
1. json数据的遍历
2. RecyclerView实现循环的列表
3. 每块元素里的元素点击 : 未选中的话, 首次点击显示"selected", 点击"selected"则进行下一步数据处理
4. 设置默认的选择的元素, 显示selected

代码

1. layout/item_region.xml 组件元素

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp">   // 这里的高度需要注意, 就是每个需要遍历的元素的高度, 千万要写成不match_parent
    <LinearLayout
        android:id="@+id/item_region"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@drawable/bottom_border_white"
        android:gravity="center_vertical">
        <TextView
            android:id="@+id/regionName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_weight="2"
            android:text="China"
            android:textColor="@color/colorPrimary"
            android:textSize="16sp" />
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/selectedBtn"
                android:layout_width="80dp"
                android:layout_height="wrap_content"
                android:text="Selected"
                android:textColor="@color/colorPrimary"
                android:textSize="16sp"
                android:visibility="invisible"
                />
            <ImageView
                android:layout_width="10dp"
                android:layout_height="15dp"
                android:layout_marginLeft="15dp"
                android:src="@drawable/right_arrow" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

2. activity_update_region.xml 主页面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/main_bg_color"
    android:orientation="vertical"
    >
    <LinearLayout
        android:id="@+id/updateArea_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="40dp"
            android:gravity="center_vertical"
            android:text="All regions"
            android:textColor="@color/colorPrimary"
            android:textSize="16sp"
            android:textStyle="bold" />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/regionListRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            />
    </LinearLayout>
</RelativeLayout>

3. Myactivity.kt

import kotlinx.android.synthetic.main.activity_update_area.regionListRecyclerView

data class Country(val name: String, val code: Int, var selected: Boolean)

/**
 * 设置页
 */
class AreaupdateActivity : AppCompatActivity() {
    private lateinit var adapter: SimpleAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_update_area)

        // 读取文件内容
        val jsonString = loadJsonFromAssets(this, "country.json")
        val gson = Gson()
        val countryName = "China"
        val countrys: List<Country> = gson.fromJson(jsonString, type)
		// 设置默认的被选中的countryName selected 
        if (countryName != null) {
            for (item in countrys) {
                if (item.name == countryName){
                    item.selected = true
                }
            }
        }

        regionListRecyclerView.layoutManager = LinearLayoutManager(this)
        adapter = SimpleAdapter(countrys)
        regionListRecyclerView.adapter = adapter
		
		// 元素的点击事件
        adapter.setOnItemClickListener(object : SimpleAdapter.OnItemClickListener {
            override fun onItemClick(position: Int, item: Country) {
                println("我点击的$item")
                adapter.notifyItemChanged(position, item) // .indexOf(item)
            }
        })
    }
	
	// 如果JSON文件位于assets目录下, 这是处理非代码资源文件(如文本、JSON等)的方式。通过AssetManager来访问这些文件。
    fun loadJsonFromAssets(context: Context, fileName: String): String {
        val assetManager = context.assets
        val reader: BufferedReader
        var jsonString: String = ""
        try {
            reader = BufferedReader(InputStreamReader(assetManager.open(fileName)))
            jsonString = reader.use { it.readText() }
        } catch (e: Exception) {
            e.printStackTrace()
            // 处理异常情况
        }
        return jsonString
    }
	
	// SimpleAdapter 适配器, 监听列表元素
	// 为了代码的优雅, 应该单独写在Adapter里
    class SimpleAdapter(private val countrys: List<Country>) :
        RecyclerView.Adapter<SimpleAdapter.SimpleViewHolder>() {
        private var selectedPosition = RecyclerView.NO_POSITION
        inner class SimpleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            val regionName: TextView = itemView.findViewById(R.id.regionName)
            val selectedBtn: TextView = itemView.findViewById(R.id.selectedBtn)

            init {

                itemView.setOnClickListener {
                    // 在这里处理点击事件
                    onItemClickListener?.let { listener ->
                        selectedPosition = adapterPosition
                        notifyDataSetChanged()
                        if (selectedPosition != RecyclerView.NO_POSITION) {
                            listener.onItemClick(selectedPosition, getItem(selectedPosition))
                        }
                    }
                }
            }
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleViewHolder {
            val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.item_region, parent, false)
            return SimpleViewHolder(view)
        }

        interface OnItemClickListener {
            fun onItemClick(position: Int, item: Country)
        }

        private var onItemClickListener: OnItemClickListener? = null

        fun setOnItemClickListener(listener: OnItemClickListener) {
            onItemClickListener = listener
        }

        override fun onBindViewHolder(holder: SimpleViewHolder, position: Int) {
            val currentItem = getItem(position)
            holder.regionName.text = countrys[position].name

            // 点击的显示selected, 其他隐藏
            holder.selectedBtn.visibility = if (position == selectedPosition) View.VISIBLE else View.INVISIBLE
            // 初始化数据 currentItem.selected为true的显示
            // 点击的时候 原currentItem.selected为true的变为false, 点击的这个元素selected显示
             if (currentItem.selected) {
                 currentItem.selected = !currentItem.selected
                holder.selectedBtn.visibility = View.VISIBLE  
                println("我显示着")
            }

            // 点击selected
            holder.selectedBtn.setOnClickListener {
                var countryStr = currentItem.name
                CoroutineScope(Dispatchers.IO).launch {
                    updateInfo(countryStr) // 更新用户数据(自定义function)
                }
            }
        }

        override fun getItemCount(): Int = countrys.size

        fun getItem(position: Int): Country {
            return countrys[position]
        }
    }
}

4. assets/country.json (示例)

[{
		"selected": false,
		"country_id": 100006,
		"country_code": 244,
		"name": "Angola",
		"country_name_cn": "安哥拉",
		"ab": "AO"
	},
	{
		"selected": false,
		"country_id": 100008,
		"country_code": 355,
		"name": "Albania",
		"country_name_cn": "阿尔巴尼亚",
		"ab": "AL"
	}]

完成!
其中难点是上述第3条功能, 因为需要操作item里的元素, 相比item, 里面的元素更难获取和操作, 其次是selected的初始化和两次点击的操作, 还有点击时其他selected的隐藏

对比uniapp的感受 :
① 组件的适配器和数据监听交给开发者去写, 此为难度一, 而uniapp仅需一个v-for完成遍历
② 点击事件的处理, Android需要开发者自己找到选中的元素及其子元素, 再对其及其兄弟元素操作, 有点类似jquery, 操作dom节点, 而非vue一样操作数据, 逻辑性会更强一些

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

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

相关文章

增加一个按钮,批量获取凭证号

create PROCEDURE Cux_Ar_ServiceLedger_Voucher_ProcOrgId Int ,result Int output AS BEGIN SET NOCOUNT ONDECLARE Date DATETIME IF OrgId 0 or OrgIdBEGIN RAISERROR(N获取当前组织ID失败&#xff01;, 16, 1) RETURNEND SET Date GETDATE()BEGIN TRANSACTION BEGIN…

职场中这三大效应,读懂受用终身

01 霍桑效应 “霍桑效应”也称“宣泄效应”。 霍桑工厂是一家电器公司的分厂。为了提高员工的工作效率&#xff0c;工厂增设了许多娱乐设施&#xff0c;改善工作环境&#xff0c;提高各项福利&#xff0c;但奇怪的是&#xff0c;成效并不理想。 工厂为此又做了许多尝试&…

zabbix应用教程:基于Nginx页面响应的日志监控用例

作者 乐维社区&#xff08;forum.lwops.cn&#xff09;许远 背景&#xff1a;某公司基于 Nginx 服务器搭建的网站&#xff0c;需要监控页面响应耗时的数据&#xff0c;因此该公司搭建了zabbix开源监控系统&#xff0c;当监控到页面响应时间超过3000ms阈值时&#xff0c;就进行告…

C语言 | Leetcode C语言题解之第313题超级丑数

题目&#xff1a; 题解&#xff1a; int nthSuperUglyNumber(int n, int* primes, int primesSize) {long dp[n 1];int pointers[primesSize];for (int i 0; i < primesSize; i) {pointers[i] 0;}long nums[primesSize];for (int i 0; i < primesSize; i) {nums[i] …

Mosh|SQL教程第六弹

一、视图 1、创建视图CREATE VIEW viewname AS 这样就可以在左侧导航栏看到新增的view了&#xff0c;如果没有的话刷新一下就好了 可以把视图当表格使用 或者 注意&#xff1a;视图不存储数据&#xff0c;数据存储在表中 练习&#xff1a;创建一个视图&#xff0c;叫做客户结…

2023华为od机试C卷【掌握单词的个数】Python

2023华为od机试C卷【掌握单词的个数】 问题分析 输入内容&#xff1a; 具体的单词数量和单词列表。一个包含字母和 ? 的字符串&#xff0c;该字符串表示可以用来构词的字符。 目标&#xff1a; 计算哪些单词可以由给定字符以及 ?&#xff08;作为通配符&#xff09;构成。 …

政安晨:【Keras机器学习示例演绎】(五十七)—— 基于Transformer的推荐系统

目录 介绍 数据集 设置 准备数据 将电影评分数据转换为序列 定义元数据 创建用于训练和评估的 tf.data.Dataset 创建模型输入 输入特征编码 创建 BST 模型 开展培训和评估实验 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的…

Python 中的 “私有”(实现)类

在 Python 中&#xff0c;尽管没有严格意义上的私有类&#xff08;private class&#xff09;&#xff0c;但可以通过命名约定和语言特性来模拟实现类似的访问控制。Python 的私有类的概念通常是通过以下几种方式来实现&#xff1a; 1、问题背景 我正在编码一个由两部分组成的…

数值分析——分段低次插值

关键字&#xff1a;Matalb&#xff1b;曲线拟合&#xff1b;高次病态特性&#xff1b;分段低次插值 系列文章目录 数值分析——拉格朗日插值 数值分析——牛顿插值多项式 数值分析——埃尔米特&#xff08;Hermit&#xff09;插值 文章目录 系列文章目录前言一、理论推导1.高次…

Python面试宝典第25题:括号生成

题目 数字n代表生成括号的对数&#xff0c;请设计一个函数&#xff0c;用于能够生成所有可能的并且有效的括号组合。 备注&#xff1a;1 < n < 8。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()"…

泛化的最近点迭代法(Generalized-ICP)

Generalized-ICP算法是由斯坦福大学的Aleksandr V. Segal、Dirk Haehnel和Sebastian Thrun提出的&#xff0c;于2009年在Robotics science and system会议上发表。 GICP是一种ICP算法的变体&#xff0c;其原理与ICP算法相同&#xff0c;之所以称为泛化的ICP算法是因为大多数ICP…

MongoDB性能调优

文章目录 MongoDB性能调优MongoDB性能不佳原因影响MongoDB性能的因素MongoDB性能监控工具mongostatmongotopProfiler模块db.currentOp() MongoDB性能调优 MongoDB性能不佳原因 慢查询阻塞等待硬件资源不足 1,2通常是因为模型/索引设计不佳导致的 排查思路&#xff1a;按1-2…

再论国产数据库的选择

如何选择国产数据库? 上篇写得很水,本来不想继续写了! 毕竟写一篇很费心力,大家觉得好,就点下广告支持下吧! 因为今天看到类总的朋友圈,发个公号文章.里面讲个故事, 数据最前线 关注数据生态&#xff0c;讲述开源故事 13篇原创内容 公众号 某国产数据库救援现场惊魂8小时…

Golang | Leetcode Golang题解之第313题超级丑数

题目&#xff1a; 题解&#xff1a; func nthSuperUglyNumber(n int, primes []int) int {dp : make([]int, n1)m : len(primes)pointers : make([]int, m)nums : make([]int, m)for i : range nums {nums[i] 1}for i : 1; i < n; i {minNum : math.MaxInt64for j : range…

【大模型框架】【推理加速】KV CACHE

1. 思想 核心思想是空间换时间来进行加速 2. 基本原理 transformer是自回归生成模型&#xff0c;abc三个字符预测def 过程是: abc -> d d进行回归得到abc,回归讲究的是回去&#xff0c;如香港回归 abcd -> e 这里abc的运算中间值Q V可以保存下来作为Cache&#xf…

爬猫眼电ying

免责声明:本文仅做分享... 未优化,dp简单实现 from DrissionPage import ChromiumPage import time urlhttps://www.maoyan.com/films?showType2&offset60 pageChromiumPage()page.get(url) time.sleep(2) for i in range(1,20):# 爬取的页数for iu_list in page.eles(.…

c语言指针中“数组名的理解”以及“一维数组传参”的本质

数组名的理解 数组名就是数组首元素的地址。 例如&#xff1a;输入一个数组的所有元素&#xff0c;再打印出来。 另一种写法 以上可以看出&#xff1a;*arri&#xff09; arr[i] 也即是&#xff1a;*(iarr)i[arr] 本质上无区别 1&#xff1a;数组就是数组&#xff0c;是一块…

List 31

ArrayList底层原理 Linkedlist的底层原理 使用场景

扎克伯格说Meta训练Llama 4所需的计算能力是Llama 3的10倍

Meta 公司开发了最大的基础开源大型语言模型之一 Llama&#xff0c;该公司认为未来将需要更强的计算能力来训练模型。马克-扎克伯格&#xff08;Mark Zuckerberg&#xff09;在本周二的 Meta 第二季度财报电话会议上表示&#xff0c;为了训练 Llama 4&#xff0c;公司需要比训练…

做管理,一定要避开这6个坑,才能成就优秀管理者

做管理&#xff0c;一定要避开这6个坑&#xff0c;才能成就优秀管理者 一、被平庸的员工绑架 要是领导不敢或者不愿意惩罚或者开除那些没完成任务的员工&#xff0c;那优秀的员工就会觉得&#xff0c;做得好做得差都一样&#xff0c;那谁还愿意努力呢&#xff1f; 二、总想改变…