微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android_Jetpack:Room与LiveData、ViewModel的结合使用

如果不使用LiveData自动获取数据的变化,那么当每次数据库中的数据发生变化时,我们都要开启一个工作线程去重新获取数据库中的数据。
比如说,在进入页面时,要获取数据库中全部学生信息列表,一般我们会这么写:

thread{
    studentList = studentDao.getStudentList() as MutableList<Student>
    runOnUiThread {
        arrayAdapter = ArrayAdapter(this,android.R.layout.simple_list_item_1,studentList)
        listView.adapter = arrayAdapter
    }
}

首先开个工作线程去获取数据库中存储的学生列表,然后再回到UI线程中进行界面更新。这样既不方便又有可能因为忘记开线程而造成的程序出错,但是,结合LiveData及viewmodel,就可以在数据发生变化时,通过LiveData组件通知View层,实现数据的自动更新。
要想实现这个功能,我们需要对程序做如下改动:
修改学生表Dao文件
这里我们希望当学生列表数据发生变化时,能够收到实时通知,因此,我们将getStudentList()方法的返回对象用LiveData包装起来。

package com.example.jetpacktest.room

import androidx.lifecycle.LiveData
import androidx.room.*

@Dao
interface StudentDao {
    @Insert
    fun insertStudent(student:Student)
    @Delete
    fun deleteStudent(student: Student)
    @Update
    fun updateStudent(student: Student)
    @Query("SELECT * FROM student")
    fun getStudentList():LiveData<List<Student>>
    @Query("SELECT * FROM student WHERE id = :id")
    fun getStudentById(id:Long):Student
}

②创建Studentviewmodel类。
在Studentviewmodel类中调用StudentDao里的getStudentList()方法

package com.example.jetpacktest.room

import androidx.lifecycle.viewmodel

class Studentviewmodel(studentDao: StudentDao) : viewmodel() {
    var studentLiveData = studentDao.getStudentList()
}

③创建StudentviewmodelFactory类。
因为我们在Studentviewmodel类中传递了StudentDao参数,因此我们需要有这么个类实现viewmodelProvider.Factory接口,以便于将StudentDao在实例化时传入。
以下写法为模板化写法,根据实际需求参数不同,做微调即可。

package com.example.jetpacktest.room

import androidx.lifecycle.viewmodel
import androidx.lifecycle.viewmodelProvider

class StudentviewmodelFactory(private val studentDao: StudentDao): viewmodelProvider.Factory {
    override fun <T : viewmodel?> create(modelClass: Class<T>): T {
        return Studentviewmodel(studentDao) as T
    }
}

④在Activity中实例化Studentviewmodel,并监听LiveData的变化。

package com.example.jetpacktest.room

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.Observer
import androidx.lifecycle.viewmodelProvider
import com.example.jetpacktest.AppDatabase
import com.example.jetpacktest.R
import kotlinx.android.synthetic.main.activity_room_test_main.*
import kotlin.concurrent.thread

class RoomTestMainActivity : AppCompatActivity() {
    private var studentList:MutableList<Student> = arraylistof()
    private lateinit var arrayAdapter:ArrayAdapter<Student>
    lateinit var studentDao: StudentDao
    lateinit var viewmodel: Studentviewmodel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_room_test_main)
        studentDao = AppDatabase.getDatabase(this).studentDao()
//        thread{
//            studentList = studentDao.getStudentList() as MutableList<Student>
//            runOnUiThread {
//                arrayAdapter = ArrayAdapter(this,android.R.layout.simple_list_item_1,studentList)
//                listView.adapter = arrayAdapter
//            }
//        }

		//Room与LiveData、viewmodel的结合使用,代替上面注释掉的部分
        arrayAdapter = ArrayAdapter(this,android.R.layout.simple_list_item_1,studentList)
        listView.adapter = arrayAdapter
        viewmodel = viewmodelProvider(this,StudentviewmodelFactory(studentDao)).get(Studentviewmodel::class.java)
        viewmodel.studentLiveData.observe(this, Observer { stList->
            studentList.clear()
            studentList.addAll(stList)
            arrayAdapter.notifyDataSetChanged()
        })
        ......
    }
}

运行程序,onChanged()方法会被自动调用,之后其他增删改操作都会在该方法通知Adapter刷新数据,其他什么都不用做。
如:

fun addClick(view: View){
    if (nameEdt.text.toString() == "" || ageEdt.text.toString() == ""){
        Toast.makeText(this,"姓名或年龄不能为空",Toast.LENGTH_SHORT).show()
        return
    }
    val student = Student(nameEdt.text.toString(),ageEdt.text.toString().toInt())
    thread{
        studentDao.insertStudent(student)
    }
}

页面自动刷新。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐