【问题标题】:FireBase and LiveData the text on in the cardviews don't appear and the content doesn't update (I can see the cards but there is no content)FireBase 和 LiveData 卡片视图中的文本没有出现,内容也没有更新(我可以看到卡片,但没有内容)
【发布时间】:2020-10-22 12:27:04
【问题描述】:

我使用 Firebase 实时数据库。我有 RecycleViewAdapter 类,一个显示 recycleview 的 Fragment,一个为 Fragment 提供数据的 ViewHolder 类(我使用 LiveData),还有一个与 firebase 数据库通信的 Repository 类。

class Post(
var title: String = "",
var dateStr: String = "",
var desc: String = "",
var id: String = "")

类 PostsFireBaseRepository(val bucketListViewModel: BucketListViewModel) {

private val path: String = "posts"

init {
    initPostsListener()
}


fun getAllPosts() {
    var data = mutableListOf<Post>()
    FirebaseDatabase.getInstance().reference
        .child(FirebaseAuth.getInstance().currentUser?.uid.toString())
        .child(path)
        .addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                for (ds in dataSnapshot.children) {
                    val newPost = dataSnapshot.getValue<Post>(Post::class.java)
                    if (newPost != null) {
                        data.add(newPost)
                    }
                }
                bucketListViewModel.allPosts.value = data
                bucketListViewModel.dataChanged()
            }

            override fun onCancelled(error: DatabaseError) {

            }
        })

}

     class BucketListViewModel() : ViewModel() {
        
             private val repository: PostsFireBaseRepository
        
             var recyclerViewAdapter: BucketListRecyclerViewAdapter? = null
        
             var allPosts: MutableLiveData<MutableList<Post>> = MutableLiveData<MutableList<Post>>()
        
    
         init {
              repository = PostsFireBaseRepository(this)
              repository.getAllPosts()
         }

      fun dataChanged() {
            recyclerViewAdapter?.notifyDataSetChanged()
        }

}

class BucketListFragment : Fragment(), DatePickerDialogFragment.OnDateSelectedListener,
BucketListRecyclerViewAdapter.PostItemClickListener {

private lateinit var bucketListViewModel: BucketListViewModel

private lateinit var recyclerViewAdapter: BucketListRecyclerViewAdapter

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

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    setupRecyclerView()

    bucketListViewModel = ViewModelProvider(requireActivity()).get(BucketListViewModel::class.java)
    bucketListViewModel.allPosts.observe(viewLifecycleOwner) { posts ->
        recyclerViewAdapter.addAll(posts)
    }

}

BucketListRecyclerViewAdapter

class BucketListRecyclerViewAdapter() : RecyclerView.Adapter<BucketListRecyclerViewAdapter.ViewHolder>() {

interface PostItemClickListener {
    fun onItemLongClick(position: Int, view: View, post: Post?): Boolean
    fun onItemClick(position: Int, view: View, post: Post?): Boolean
}

private var postList = mutableListOf<Post>()

private var lastDeleted: Post? = null
private var lastDeletedPos: Int? = null

var postClickListener: PostItemClickListener? = null

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.bucketlist_post_row, parent, false)
    return ViewHolder(view)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val post = postList[holder.adapterPosition]

    holder.post = post

    holder.tvTitle.text = post.title
    holder.tvDesc.text = post.desc
    holder.tvRowDate.text = post.dateStr
}

override fun getItemCount() = postList.size

fun addItem(post: Post) {
    postList.add(post)
    notifyItemInserted(postList.size-1)
}

fun addAll(posts: List<Post>) {
    postList.clear()
    postList.addAll(posts)
    notifyDataSetChanged()
}

【问题讨论】:

  • 请同时添加您的Post 类的内容。
  • 我编辑了帖子。

标签: android firebase firebase-realtime-database android-livedata


【解决方案1】:

在您的onDataChange 方法中,您需要通知该适配器其数据已更改,否则它不会重新绘制 UI 元素。为此,请在更新适配器的数据源后在适配器上调用 notifyDataSetChanged()

比如:

override fun onDataChange(dataSnapshot: DataSnapshot) {
    for (ds in dataSnapshot.children) {
        val newPost = dataSnapshot.getValue<Post>(Post::class.java)
        if (newPost != null) {
            data.add(newPost)
        }
    }
    bucketListViewModel.allPosts.value = data
    adapter.notifyDataSetChanged();        
}

到达适配器的具体方式取决于您的代码。例如,在您的情况下,您可能必须将一个方法添加到您从 onDataChange 调用的 BucketListViewModel 中,然后调用适配器。

【讨论】:

  • 感谢您的回答。我试过这个,但不幸的是它对我不起作用。也许我的代码有其他问题。我用更改编辑了代码。我在帖子中添加了recycleview适配器类,我在其中调用了notifyDataSetChanged函数。
猜你喜欢
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2018-01-26
相关资源
最近更新 更多