You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中Instagram克隆项目评论RecyclerView不显示问题

Instagram克隆项目评论RecyclerView不显示问题

我用Kotlin和Firebase开发Instagram克隆项目,帖子详情页的评论RecyclerView完全看不到。已经确认commentList数据正常,但不管有没有评论,RecyclerView和无评论提示文本都不显示。以下是相关代码和布局文件:


相关代码

DetailedPostActivity.kt

class DetailedPostActivity : AppCompatActivity() {

    val auth = Firebase.auth
    private lateinit var binding: ActivityDetailedPostBinding
    private lateinit var viewmodel: DetailedPostViewmodel
    private lateinit var post: Post
    private lateinit var adapter: CommentsAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDetailedPostBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.commentRecyclerView.layoutManager = LinearLayoutManager(this@DetailedPostActivity)
        adapter = CommentsAdapter(arrayListOf())
        binding.commentRecyclerView.adapter = adapter

        post = intent.getSerializableExtra("post") as Post

        viewmodel = ViewModelProvider(this@DetailedPostActivity).get(DetailedPostViewmodel::class.java)
        viewmodel.getData(post.postId)
        observeLiveData()


        binding.sendBtn.setOnClickListener { send(it) }
        binding.likeBtn.setOnClickListener { like(it) }

    }

    fun observeLiveData() {
        viewmodel.postLiveData.observe(this@DetailedPostActivity, Observer { post ->
            try {
                binding.postEmailText.setText(HomePageActivity.hashMapUsers.get(post.userId)!!.email)
                Picasso.get().load(HomePageActivity.hashMapUsers.get(post.userId)!!.userPhotoUrl)
                    .into(binding.profilePhotoImageView)
            } catch (e: Exception) {
                println(e.printStackTrace())
            }
            binding.likeCountDetail.setText("${post.likedUsers.size} kişi beğendi")
            Picasso.get().load(post.imageUrl).into(binding.postImageView)
        })
        viewmodel.commentsLiveData.observe(this@DetailedPostActivity, Observer { commentList ->
            if (!commentList.isEmpty()) {
                adapter.yorumlariGuncelle(commentList)
                binding.commentRecyclerView.visibility = View.VISIBLE
                binding.nullCommentText.visibility = View.GONE
            } else {
                binding.commentRecyclerView.visibility = View.GONE
                binding.nullCommentText.visibility = View.VISIBLE
            }

        })

        viewmodel.nullLiveData.observe(this@DetailedPostActivity, Observer { bool ->
            if (bool) {
                binding.nullCommentText.visibility = View.VISIBLE
                binding.commentRecyclerView.visibility = View.GONE
            } else {
                binding.nullCommentText.visibility = View.GONE
            }
        })

    }


    private fun send(view: View) {
        val commentText = binding.commentText.text.toString()
        binding.commentText.text.clear()
        if (!commentText.isEmpty()) {
            val comment = Comment(auth.uid!!, post.postId, commentText)
            viewmodel.addComment(comment)
            adapter.notifyDataSetChanged()
        }else{
            Toast.makeText(this@DetailedPostActivity, "Yorum Yazınız!", Toast.LENGTH_LONG).show()
        }
    }


    private fun like(view: View){
        val userId = auth.uid
        val user = HomePageActivity.hashMapUsers.get(userId)
        user?.let {user->
            if(user.userId in post.likedUsers){
                post.likedUsers.remove(user.userId)
                binding.likeBtn.setText("LIKED")
            }else{
                post.likedUsers.add(user.userId)
                binding.likeBtn.setText("LIKE")
                }
            adapter.notifyDataSetChanged()
        }
    }
}

DetailedPostViewmodel.kt

class DetailedPostViewmodel(application: Application) : AndroidViewModel(application) {
    val firestore = Firebase.firestore
    val postLiveData = MutableLiveData<Post>()
    val commentsLiveData = MutableLiveData<ArrayList<Comment>>()
    val nullLiveData = MutableLiveData<Boolean>()
    val commentList = ArrayList<Comment>()

    fun getData(postId:String) {
        nullLiveData.value = false

        //******İLGİLİ POSTU ALIYORUZ**********
        firestore.collection("Posts").document(postId).get().addOnSuccessListener {
            val hashmap = it.data
            hashmap?.let{hashmap->
                val userId = hashmap["userId"] as? String
                val imageUrl = hashmap["imageUrl"] as? String
                val outline = hashmap["outline"] as? String
                if(userId != null && imageUrl != null && outline != null){
                    val post = Post(userId,imageUrl,outline)
                    postLiveData.value = post
                }
            }
        }


        //**************TAKING COMMENTS*************
        firestore.collection("Posts").document(postId)
            .collection("Comments").orderBy("date",Query.Direction.DESCENDING)
            .addSnapshotListener { value, error ->
                if (error != null) {
                    Toast.makeText(getApplication(), error.localizedMessage, Toast.LENGTH_LONG)
                        .show()
                } else {
                    if (value != null && !value.isEmpty) {
                        val documents = value.documents
                        commentList.clear()
                        for (document in documents) {
                            val commentMap = document.get("comment") as? Map<String, Any>
                            commentMap?.let { map ->
                                val userId = map["userId"] as? String
                                val commentText = map["commentText"] as? String
                                if (userId != null && commentText != null) {
                                    commentList.add(Comment(userId, postId, commentText))
                                }
                            }
                        }
                        println(commentList)
                        commentsLiveData.value = commentList
                    } else {
                        nullLiveData.value = true
                    }
                }
            }
    }

    fun addComment(comment:Comment){
        firestore.collection("Posts").document(comment.postId)
            .collection("Comments")
            .add(hashMapOf("comment" to comment,"date" to Timestamp.now()))
            .addOnSuccessListener {
                Toast.makeText(getApplication(),"YORUMUNUZ PAYLAŞILDI!",Toast.LENGTH_SHORT).show()
                getData(comment.postId)
            }.addOnFailureListener {
                Toast.makeText(getApplication(),"YORUM YAPILAMADI!",Toast.LENGTH_LONG).show()
            }
    }
}

CommentsAdapter.kt

package com.example.firebasedeneme.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.firebasedeneme.R
import com.example.firebasedeneme.databinding.RecyclerCommentRowBinding
import com.example.firebasedeneme.model.Comment
import com.example.firebasedeneme.views.HomePageActivity

class CommentsAdapter(val commentList:ArrayList<Comment>) : RecyclerView.Adapter<CommentsAdapter.CommentVH>(){
    inner class CommentVH(val binding:RecyclerCommentRowBinding) : RecyclerView.ViewHolder(binding.root) {

    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommentVH {
        val binding = DataBindingUtil.inflate<RecyclerCommentRowBinding>(LayoutInflater.from(parent.context),
            R.layout.recycler_comment_row,parent,false)
        return CommentVH(binding)
    }

    override fun getItemCount(): Int {
        return commentList.size
    }

    override fun onBindViewHolder(holder: CommentVH, position: Int) {
        /*holder.binding.postEmailText.text = HomePageActivity.hashMapUsers.get(commentList[position].userId)!!.email
        holder.binding.yorumTextView.text = commentList[position].commentText
        //Picasso.get().load(HomePageActivity.hashMapUsers.get(commentList[position].userId)!!.userPhotoUrl).into(holder.binding.profilePhotoImageView)
         */
        val comment = commentList[position]
        holder.binding.comment = comment

        val user = HomePageActivity.hashMapUsers.get(comment.userId)
        user?.let{
            holder.binding.user = user
        }
    }

    fun yorumlariGuncelle(newCommentList:ArrayList<Comment>){
        commentList.clear()
        commentList.addAll(newCommentList)
        notifyDataSetChanged()
    }
}

布局文件

recycler_comment_row.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="user"
            type="com.example.firebasedeneme.model.User" />

        <variable
            name="comment"
            type="com.example.firebasedeneme.model.Comment" />
    </data>

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

    <ImageView
        android:id="@+id/profilePhotoImageView"
        android:layout_width="99dp"
        android:layout_height="72dp"
        android:downloadUrl="@{user.userPhotoUrl}"/>

    <TextView
        android:id="@+id/postEmailText"
        android:layout_width="306dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:paddingRight="200dp"
        android:text="@{user.email}" />

    </LinearLayout>

    <TextView
        android:id="@+id/yorumTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15sp"
        android:text="@{comment.commentText}"/>

</LinearLayout></layout>

activity_detailed_post.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/profilePhotoImageView"
            android:layout_width="99dp"
            android:layout_height="72dp"
            android:src="@drawable/baseline_person_24"/>

        <TextView
            android:id="@+id/postEmailText"
            android:layout_width="306dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:paddingRight="200dp"
            android:text="NICKNAME" />
    </LinearLayout>

    <TextView
        android:id="@+id/postOutlineText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAlignment="center"/>


    <ImageView
        android:id="@+id/postImageView"
        android:layout_width="249dp"
        android:layout_height="207dp"
        android:layout_gravity="left"
        android:layout_marginLeft="20dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/likeCountDetail"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textColor="#2E53BD"
            android:textSize="12sp"
            android:gravity="left"
            android:text="22 KİŞİ BEĞENDİ"
            android:paddingLeft="10dp"/>

    </LinearLayout>



    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <Button
            android:id="@+id/likeBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="LIKE"/>
        <EditText
            android:id="@+id/commentText"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:hint="Yorum Yap..."
            android:textSize="22sp"/>
        <Button
            android:id="@+id/sendBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Send"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/commentRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="20dp" />

        <TextView
            android:id="@+id/nullCommentText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="NO ANY COMMENT!"
            android:textAlignment="center"
            android:textSize="32sp" />
    </LinearLayout>
</LinearLayout>

> </layout>

详情页布局


问题排查与修复方案

1. 布局高度冲突(核心问题)

RecyclerView所在的父LinearLayout高度设置为wrap_content,但RecyclerView自身高度是match_parent,导致父布局无法计算有效空间,直接挤压隐藏了RecyclerView和提示文本。
修复:将RecyclerView的父LinearLayout高度改为match_parent:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

2. 布局语法错误

activity_detailed_post.xml末尾存在冗余代码> </layout>,会导致布局解析异常,直接删除该行。

3. 数据绑定延迟

在CommentsAdapter的onBindViewHolder方法末尾添加executePendingBindings(),确保数据绑定立即生效:

override fun onBindViewHolder(holder: CommentVH, position: Int) {
    val comment = commentList[position]
    holder.binding.comment = comment

    val user = HomePageActivity.hashMapUsers.get(comment.userId)
    user?.let{
        holder.binding.user = user
    }
    holder.binding.executePendingBindings()
}

4. 冗余的LiveData观察逻辑

commentsLiveData和nullLiveData的观察逻辑重叠,合并为单一逻辑避免状态冲突:

viewmodel.commentsLiveData.observe(this) { commentList ->
    if (commentList.isNotEmpty()) {
        adapter.yorumlariGuncelle(commentList)
        binding.commentRecyclerView.visibility = View.VISIBLE
        binding.nullCommentText.visibility = View.GONE
    } else {
        binding.commentRecyclerView.visibility = View.GONE
        binding.nullCommentText.visibility = View.VISIBLE
    }
}
// 移除nullLiveData的观察代码

5. 多余的Adapter刷新

删除send()方法中的adapter.notifyDataSetChanged(),因为addComment()已经调用getData()刷新LiveData,会自动触发Adapter更新。


内容的提问来源于stack exchange,提问作者Emre Dursun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:38:08