【发布时间】:2018-06-09 00:12:22
【问题描述】:
我有一个简单的 RecyclerView,其中 CardView 作为列表项。从 Firebase 实时数据库检索并存储到 noteList 的列表中的每个项目。 Firebase sdk 为 onChildAdded、onChildChanged 和其他少数几个提供回调。现在我设计了用于回收器视图的适配器以接收 ArrayList。每当实时数据库中的数据发生更改时,我都会使用回调向noteList 添加或删除项目。每当特定项目的值发生更改时,都会调用 onChildChanged 方法。我想在noteList 中反映这种变化并通知适配器。
当然,我们可以天真地搜索 List 中与更改元素的键匹配的每个元素并更新它。但这可以以更好/有效的方式完成吗?
class NoteListAdapter(var data: MutableList<Note>, val onItemClick: (Note) -> Unit) : RecyclerView.Adapter<NoteListAdapter.ViewHolder>() {
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
holder!!.bindNoteItem(data[position])
}
override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent?.context)
.inflate(R.layout.card_note, parent, false)
return ViewHolder(v, onItemClick)
}
class ViewHolder(v: View, val onItemClick: (Note) -> Unit): RecyclerView.ViewHolder(v) {
fun bindNoteItem(note: Note) {
...
}
}
}
HomeActivity.kt
class HomeActivity : AppCompatActivity() {
lateinit var mDb: DatabaseReference
val noteList: MutableList<Note> = ArrayList()
lateinit var adapter: NoteListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
addNoteFAB.setOnClickListener { addNote() }
mDb = FirebaseDatabase.getInstance().reference
adapter = NoteListAdapter(noteList, this::editNote)
noteListRecycler.layoutManager = LinearLayoutManager(this)
noteListRecycler.adapter = adapter
loadNotes()
}
fun addNote() {
val intent = Intent(this, EditNoteActivity::class.java)
intent.putExtra(EditNoteActivity.EXTRA_NOTE, Note())
startActivity(intent)
}
fun loadNotes() {
val path = "users/" + FirebaseAuth.getInstance().currentUser?.uid + "/notes"
mDb.child(path ).addChildListener({
// onChildAdded
dataSnapshot, prevChildName ->
val note = dataSnapshot?.getValue(Note::class.java)!!
note.id = dataSnapshot.key
noteList += note
adapter.notifyDataSetChanged()
}, {
// onChildRemoved
dataSnapshot ->
noteList.remove(dataSnapshot?.getValue(Note::class.java))
adapter.notifyDataSetChanged()
}, {
// onChildChanged, TODO: update the change in elements value in noteList
dataSnapshot, s ->
})
}
fun editNote(note: Note) {
val i = Intent(this, EditNoteActivity::class.java)
i.putExtra(EditNoteActivity.EXTRA_NOTE, note)
startActivity(i)
}
}
PS:addChildListener 是一个扩展函数。 (检查代码中的 cmets 以获取回调名称)
由于dataSnapshot 只能告诉我们更改的键和值(据我从文档中知道),我将如何在不知道更改元素索引的情况下更新noteList?或者真的有办法获取索引吗?
【问题讨论】:
标签: android firebase arraylist firebase-realtime-database kotlin