gpt4 book ai didi

android - Room、ViewModel 和 LiveData 数据更改后重新加载 RecyclerView

转载 作者:行者123 更新时间:2023-12-02 13:17:41 28 4
gpt4 key购买 nike

我连续几天尝试解决问题,但没有成功。每当数据库(DB Room)中特定模型的记录发生变化时,我想更新我的recyclerView。我使用 ViewModel 来处理模型数据,记录列表存储在 LiveData 中。

数据库

@Database(entities = arrayOf(Additive::class), version = ElementDatabase.DB_VERSION, exportSchema = false)
abstract class ElementDatabase() : RoomDatabase() {

companion object {
const val DB_NAME : String = "element_db"
const val DB_VERSION : Int = 1

fun get(appContext : Context) : ElementDatabase {
return Room.databaseBuilder(appContext, ElementDatabase::class.java, DB_NAME).build()
}
}

abstract fun additivesModels() : AdditiveDao

}

型号

@Entity
class Additive {

@PrimaryKey @ColumnInfo(name = "id")
var number : String = ""
var dangerousness : Int = 0
var description : String = ""
var names : String = ""
var notes : String = ""
var risks : String = ""
var advice : String = ""
}

@Dao
interface AdditiveDao {

@Query("SELECT * FROM Additive")
fun getAllAdditives() : LiveData<List<Additive>>

@Query("SELECT * FROM Additive WHERE id = :arg0")
fun getAdditiveById(id : String) : Additive

@Query("DELETE FROM Additive")
fun deleteAll()

@Insert(onConflict = REPLACE)
fun insert(additive: Additive)

@Update
fun update(additive: Additive)

@Delete
fun delete(additive: Additive)
}

View 模型

class AdditiveViewModel(application: Application) : AndroidViewModel(application) {

private var elementDatabase : ElementDatabase
private val additivesModels : LiveData<List<Additive>>

init {
this.elementDatabase = ElementDatabase.get(appContext = getApplication())
this.additivesModels = this.elementDatabase.additivesModels().getAllAdditives()
}

fun getAdditivesList() : LiveData<List<Additive>> {
return this.additivesModels
}

fun deleteItem(additive : Additive) {
DeleteAsyncTask(this.elementDatabase).execute(additive)
}

private class DeleteAsyncTask internal constructor(private val db: ElementDatabase) : AsyncTask<Additive, Void, Void>() {

override fun doInBackground(vararg params: Additive): Void? {
db.additivesModels().delete(params[0])
return null
}

}
}

fragment

class AdditivesFragment : LifecycleFragment() {

private var viewModel : AdditiveViewModel? = null
private var adapter : AdditivesAdapter? = null

companion object {
fun newInstance() : AdditivesFragment {
val f = AdditivesFragment()
val args = Bundle()

f.arguments = args
return f
}
}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater?.inflate(R.layout.fragment_additives, container, false)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
this.adapter = AdditivesAdapter(ArrayList<Additive>())
this.additives_list.layoutManager = GridLayoutManager(this.context, 2, GridLayoutManager.VERTICAL, false)
this.additives_list.adapter = this.adapter

this.viewModel = ViewModelProviders.of(this).get(AdditiveViewModel::class.java)

this.viewModel?.getAdditivesList()?.observe(this, Observer<List<Additive>> { additivesList ->
if(additivesList != null) {
this.adapter?.addItems(additivesList)
}
})
super.onActivityCreated(savedInstanceState)
}
}

现在,我的问题是为什么观察者只被调用一次(在 fragment 的开头),然后就不再被回调?如何让观察者不断监听数据库中的变化(插入、更新、删除),以便我的recyclerView立即更新?非常感谢您的任何建议。

最佳答案

这是你犯错误的地方:

 this.viewModel = ViewModelProviders.of(this).get(AdditiveViewModel::class.java)

当您在fragment内部时,您正在传递this,这对某些人来说非常令人不安,因为它不是语法错误而是逻辑错误。您必须传递 activity!! 相反,它将像这样:

this.viewModel = ViewModelProviders.of(activity!!).get(AdditiveViewModel::class.java)

更新:
在观察数据时在 fragment 内传递 viewLifecycleOwner

mainViewModel.data(viewLifecycleOwner, Observer{})

如果您使用fragmentKtx,您可以这样初始化viewModel:

private val viewModel by viewModels<MainViewModel>()

如果您已查看ModelFactory:

private val viewModel by viewModels<MainViewModel>{
viewModelFactory
}

使用这种方法,您不需要调用:

// you can omit this statement completely
viewModel = ViewModelProviders.of(this).get(AdditiveViewModel::class.java)

您只需开始观察数据即可..

关于android - Room、ViewModel 和 LiveData 数据更改后重新加载 RecyclerView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46000120/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com