英文:
Why does my Recyclerview add new items at random positions?
问题
在详细阅读了如何在顶部(或底部)添加项目的内容后,我意识到 list.add(position, item)
结合 notifyDataSetChanged()
是在顶部(索引 0)添加项目的正确方式。然而,在我的代码中,即使我这样做了,我的 RecyclerView 仍然在随机位置添加项目。以下是我的 CommentsActivity 代码:
class CommentsActivity : AppCompatActivity() {
// ...(省略其他部分)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...(省略其他部分)
val layoutManager = LinearLayoutManager(this)
layoutManager.reverseLayout = true
layoutManager.stackFromEnd = true
commentsActivityRecyclerView!!.layoutManager = layoutManager
commentsList = ArrayList()
commentAdapterView = CommentsAdapter(this, commentsList as ArrayList<CommentsModel>)
commentsActivityRecyclerView!!.adapter = commentAdapterView
commentsActivityRecyclerView!!.setHasFixedSize(true)
LoadAndDisplayComments()
}
// ...(省略其他部分)
private fun LoadAndDisplayComments() {
val commentsRef = dbRef.child("Comments").child(clickedPostUid)
commentsRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
TODO("Not yet implemented")
}
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
commentsList!!.clear()
for (snapshot in p0.children) {
val getCommentDetails = snapshot.getValue(CommentsModel::class.java)
if (getCommentDetails != null) {
commentsList!!.add(0, getCommentDetails)
}
}
commentAdapterView!!.notifyDataSetChanged()
} else {
Toast.makeText(this@CommentsActivity, "No comments", Toast.LENGTH_SHORT).show()
}
}
})
}
}
这是我的 CommentsAdapter:
class CommentsAdapter(
private var commentsContext: Context,
private var commentsList: MutableList<CommentsModel>
) : RecyclerView.Adapter<CommentsAdapter.CommentsViewHolder>() {
// ...(省略其他部分)
override fun onBindViewHolder(holder: CommentsViewHolder, position: Int) {
val currentUser = FirebaseAuth.getInstance().currentUser!!
val comment = commentsList!![position]
holder.showComment.text = comment.comment
}
}
我希望新的评论可以显示在 RecyclerView 的顶部或底部。我知道如何使用 .SmoothScroll
滚动到索引 0。如果需要的话,我可以贴出 XML。谢谢。
英文:
After much reading on how to add an item to the top (or bottom), I realized that list.add(position, item)
along with notifyDataSetChanged()
is the correct way to add an item at the top (index 0). However, in my code, even after doing that, my RecyclerView adds positions at random places. Below is my CommentsActivity code:
class CommentsActivity : AppCompatActivity() {
private var clickedPostUid = ""
private var currentUserUid = ""
private lateinit var binding_commentsActivity: ActivityCommentsBinding
private val currentUserUID = FirebaseAuth.getInstance().currentUser?.uid!!
private val dbRef = FirebaseDatabase.getInstance().reference
private val uidRef = currentUserUID.let { dbRef.child("Users").child(it) }
private var commentAdapterView: CommentsAdapter? = null
private var commentsList: MutableList<CommentsModel>? = null
var commentsActivityRecyclerView: RecyclerView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding_commentsActivity = ActivityCommentsBinding.inflate(layoutInflater)
clickedPostUid = intent.getStringExtra("keyIdentifierPostUid")!!
currentUserUid = intent.getStringExtra("keyIdentifierCurrentUserUid")!!
commentsActivityRecyclerView =
binding_commentsActivity.commentsActivityRecyclerView
val layoutManager = LinearLayoutManager(this)
layoutManager.reverseLayout = true
layoutManager.stackFromEnd = true
commentsActivityRecyclerView!!.layoutManager = layoutManager
commentsList = ArrayList()
commentAdapterView = CommentsAdapter(this, commentsList as ArrayList<CommentsModel>)
commentsActivityRecyclerView!!.adapter = commentAdapterView
commentsActivityRecyclerView!!.setHasFixedSize(true)
LoadAndDisplayComments()
And this is my LoadAndDisplayComments()
private fun LoadAndDisplayComments() {
val commentsRef = dbRef.child("Comments").child(clickedPostUid)
commentsRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
TODO("Not yet implemented")
}
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists())
{
commentsList!!.clear()
for (snapshot in p0.children)
{
val getCommentDetails = snapshot.getValue(CommentsModel::class.java)
if (getCommentDetails != null) {
commentsList!!.add(0,getCommentDetails)
}
}
commentAdapterView!!.notifyDataSetChanged()
}
else{
Toast.makeText(this@CommentsActivity, "No comments" , Toast.LENGTH_SHORT).show()
}
}
})
}
This is my comments adapter
class CommentsAdapter(
private var commentsContext : Context,
private var commentsList: MutableList<CommentsModel>
) : RecyclerView.Adapter<CommentsAdapter.CommentsViewHolder>()
{
inner class CommentsViewHolder(@NonNull itemView: View) : RecyclerView.ViewHolder(itemView) {
val showComment : TextView = itemView.comments_recview_item_comment
val showImage : CircleImageView = itemView.comments_recview_item_profile_image
val showUsername : TextView = itemView.comments_recview_item_username
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommentsViewHolder {
val itemView = LayoutInflater.from(commentsContext)
.inflate(R.layout.comment_recyclerview_item, parent, false)
return CommentsViewHolder(itemView)
}
override fun getItemCount(): Int {
return commentsList!!.size
}
override fun onBindViewHolder(holder: CommentsViewHolder, position: Int) {
val currentUser = FirebaseAuth.getInstance().currentUser!!
val comment = commentsList!![position]
holder.showComment.text = comment.comment
}
I need that a new comment to be displayed at the top or bottom of the recyclerview. I know how to scroll to 0 index using .SmoothScroll
. Would be happy to post the XML if needed. Thank you.
答案1
得分: -1
原来问题不在于RecyclerView。是我在数据库中存储值的方式有问题。我在Firebase中为我的值创建了一个唯一的Id,这导致了错误。相反,我使用了.push来生成唯一键,这样就可以正常工作。
错误的方法(或者说不是我想要的方法):
val uniqueCommentId = UUID.randomUUID().toString()
.replace("-", "").toUpperCase(Locale.ROOT)
val postCommentsRef = FirebaseDatabase.getInstance().reference
.child("Comments")
.child(postId).child(uniqueCommentId)
postCommentRef.setValue()
更好的方法:
val postCommentsRef = FirebaseDatabase.getInstance().reference
.child("Comments")
.child(postId)
val commentMap = HashMap<String, Any>()
commentMap["userUid"] = currentUserUid
commentMap["postId"] = postId
commentMap["comment"] = comment
postCommentsRef.push().setValue(commentMap)
在这之后,对我来说运行良好。
英文:
Turns out the error was not in the RecyclerView. It was the way I was storing the values in the database. I was creating a unique Id for my values in Firebase that was causing the error. Instead I used .push to generate unique keys and it worked fine.
Wrong approach (or just not what I wanted):
val uniqueCommentId = UUID.randomUUID().toString()
.replace("-","").toUpperCase(Locale.ROOT)
val postCommentsRef = FirebaseDatabase.getInstance().reference
.child("Comments")
.child(postId).child(uniqueCommentId )
postCommentRef.setValue()
Better approach:
val postCommentsRef = FirebaseDatabase.getInstance().reference
.child("Comments")
.child(postId)
val commentMap = HashMap<String, Any>()
commentMap["userUid"] = currentUserUid
commentMap["postId"] = postId
commentMap["comment"] = comment
postCommentsRef.push().setValue(commentMap)
Worked fine for me after this.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论