kotlin: 用viewmodel展示数据

一,引入lifecycle

1,libs.versions.toml

[versions]
lifecycle = "2.9.1"

[libraries]
# lifecycle
androidx-lifecycle-livedata-core-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-core-ktx", version.ref = "lifecycle" }
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycle" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" }

2,build.gradle.kts

dependencies {

    //lifecycle
    implementation(libs.androidx.lifecycle.livedata.core.ktx)
    implementation(libs.androidx.lifecycle.livedata.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.lifecycle.viewmodel.ktx)

}

二,UI:

fragment_user_list.xml

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

    <Button
        android:id="@+id/getJsonButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="获取数据" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycle"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ffff00" />


</LinearLayout>

item_oneuser_layout.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textItem"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:gravity="center_vertical"
    android:background="#dddddd"
    android:padding="16dp"
    android:textSize="30sp" />

三,代码

viewmodel

package com.example.okdemo2.fragment

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class UserListViewModel: ViewModel() {
    private val _listData = MutableLiveData<MutableList<UserListItem>>()
    val listData: LiveData<MutableList<UserListItem>> = _listData

    fun updateData(newData: MutableList<UserListItem>) {
        _listData.value = newData
    }
}

model

package com.example.okdemo2.fragment

import androidx.annotation.Keep
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Keep
@Serializable
data class UserList(
    @SerialName("list")
    val `list`: MutableList<UserListItem>,
    @SerialName("curPage")
    val curPage: Int,
    @SerialName("total")
    val total: Int,
    @SerialName("totalPage")
    val totalPage: Int,
    @SerialName("token")
    val token: String,
)


@Keep
@Serializable
data class UserListItem(
    @SerialName("id")
    val id: Int,
    @SerialName("name")
    val name: String,
    @SerialName("image")
    val image: String,
)

adapter

package com.example.okdemo2.fragment

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.okdemo2.databinding.ItemOneuserLayoutBinding

class UserListAdapter : RecyclerView.Adapter<UserListAdapter.UserListViewHolder>(){

    private var userListData: MutableList<UserListItem> = mutableListOf()

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): UserListViewHolder {
        //TODO("Not yet implemented")
        var binding = ItemOneuserLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserListViewHolder(binding)
    }

    override fun onBindViewHolder(holder: UserListViewHolder, position: Int) {
        //TODO("Not yet implemented")
        val item = userListData[position]
        holder.bind(item)
    }

    override fun getItemCount(): Int {
        //TODO("Not yet implemented")
        return userListData.size
    }

    //更新数据
    fun updateData(list: MutableList<UserListItem>) {
        val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
            override fun getOldListSize(): Int {
                return userListData.size
            }

            override fun getNewListSize(): Int {
                return list.size
            }

            override fun areItemsTheSame(
                oldItemPosition: Int,
                newItemPosition: Int
            ): Boolean {
                var oldItem = userListData[oldItemPosition]
                var newItem = list[newItemPosition]
                return oldItem.id == newItem.id
            }

            override fun areContentsTheSame(
                oldItemPosition: Int,
                newItemPosition: Int
            ): Boolean {
                var oldItem = userListData[oldItemPosition]
                var newItem = list[newItemPosition]
                return oldItem.id == newItem.id &&
                        oldItem.name == newItem.name
            }

        })
        userListData.clear()
        userListData.addAll(list)
        diffResult.dispatchUpdatesTo(this)
    }

    // ViewHolder定义,用于绑定UI组件
    class UserListViewHolder(val view: ItemOneuserLayoutBinding) : RecyclerView.ViewHolder(view.root) {
        fun bind(item: UserListItem) {
            view.textItem.text = item.name
        }
    }
}

fragment


private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class UserListFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    private var _binding: FragmentUserListBinding? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //_binding = FragmentUserListBinding.inflate(inflater, container, false)
        _binding = FragmentUserListBinding.inflate(inflater, container, false)
        return binding.root
    }

    private lateinit var viewModel: UserListViewModel     //保存数据的viewmodel
    private lateinit var ulAdapter: UserListAdapter    //adapter

    private lateinit var list: ArrayList<UserListItem>   //数据

    private var curPage = 0     // id,生成数据时使用

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // 创建ViewModel实例
        viewModel = ViewModelProvider(this).get(UserListViewModel::class.java)

        // 创建Adapter实例
        ulAdapter = UserListAdapter()

        list = ArrayList<UserListItem>()  // 创建可变列表

        // 关联Adapter和ViewModel
        viewModel.listData.observe(viewLifecycleOwner, Observer {
            println("viewmodel的数据有变化...")
            ulAdapter.updateData(it)
        })

        //绑定view和adapter
        binding.recycle.layoutManager = LinearLayoutManager(context)
        binding.recycle.adapter = ulAdapter

        //按钮点击
        binding.getJsonButton.setOnClickListener {

            //创建数据
            val id1 = curPage*3+1
            val name1="张三"+id1
            val image1 = "image"+id1
            val u1 = UserListItem(id1,name1,image1)

            val id2 = curPage*3+2
            val name2="赵四"+id2
            val image2 = "image"+id2
            val u2 = UserListItem(id2,name2,image2)

            val id3 = curPage*3+3
            val name3="王五"+id3
            val image3 = "image"+id3
            val u3 = UserListItem(id3,name3,image3)

            list.add(u1)  // 添加元素
            list.add(u2)  // 添加元素
            list.add(u3)  // 添加元素

            viewModel.updateData(list)

           curPage++
        }

    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    companion object {
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            UserListFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

四,运行效果

image

posted @ 2025-09-06 22:07  刘宏缔的架构森林  阅读(9)  评论(0)    收藏  举报