需求
效果图如下 :

这个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一样操作数据, 逻辑性会更强一些
到此这篇关于android kotlin recyclerview遍历json实现列表数据的文章就介绍到这了,更多相关android kotlin recyclerview列表数据内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论