gpt4 book ai didi

android - 如何使用 Firebase 实时数据库在不知道 Android 索引的情况下更新 ArrayList 中的元素?

转载 作者:行者123 更新时间:2023-11-29 01:04:52 26 4
gpt4 key购买 nike

我有一个简单的 RecyclerView,其中 CardView 作为列表项。列表中的每一项都从 Firebase 实时数据库中检索并存储到 noteList。 Firebase sdk 为 onChildAdded、onChildChanged 和其他几个提供回调。现在我已经设计了用于回收器 View 的适配器来接收 ArrayList。每当实时数据库中的数据发生变化时,我都会使用回调向 noteList 添加或删除项目。 onChildChanged 方法在特定项目的值发生变化时被调用。我想在 noteList 中反射(reflect)这一变化并通知适配器。当然,我们可以天真地搜索 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 是一个扩展函数。 (检查回调名称的代码注释)

由于 dataSnapshot 只能告诉我们更改的键和值(据我从文档中得知),我将如何在不知道索引的情况下更新 noteList改变的元素?或者真的有办法获取索引吗?

最佳答案

到目前为止,我建议您使用 FirebaseUI专为您的用例构建。

但是,如果您真的想单独行动,那么不行,获取更新子项索引的唯一方法是在现有数据中找到它。这是 FirebaseUI 内部的示例:

private int getIndexForKey(String key) {
int index = 0;
for (DataSnapshot snapshot : mSnapshots) {
if (snapshot.getKey().equals(key)) {
return index;
} else {
index++;
}
}
throw new IllegalArgumentException("Key not found");
}

FUI uses getIndexForKey(String) 是这样的.

只要您没有下载大得离谱的列表,迭代列表在性能方面就很好。否则,您可以使用 Map<String, Integer>并查看 FUI here 的尝试.

附言:你的onChildAdded插入代码错误(项目将始终添加到末尾,即使它们位于中间)。看看如何FUI does this .

关于android - 如何使用 Firebase 实时数据库在不知道 Android 索引的情况下更新 ArrayList 中的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48007595/

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