RecyclerView shows just one item from Firebase

2019-07-04 03:28发布

问题:

I know there are few questions about this problem. But none of them didn't solve my problem especially my code is in Kotlin and new working with Fragments. Don't rush to say my question is duplicated.

My problem is exactly what title said, my RecyclerView is populated just with one item(child) from Firebase in my Fragment.

Adapter:

class NewsList(private val userList: List<News>) : RecyclerView.Adapter<NewsList.ViewHolder>() {

private val Context = this

override fun onBindViewHolder(p0: ViewHolder?, p1: Int) {
    val news: News = userList[p1]
    p0?.mesajTextView?.text = news.text
    val time = news.time
    val getTimeAgo = GetTimeAgo()
    val lastMsg = getTimeAgo.getTimeAgo(time, Context)
    p0?.timeNewsTextView!!.text = lastMsg
}

override fun onCreateViewHolder(p0: ViewGroup?, p1: Int): ViewHolder {
    val v = LayoutInflater.from(p0?.context).inflate(R.layout.news_layout, p0, false)
    return ViewHolder(v)
}

override fun getItemCount(): Int {
    return userList.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val mesajTextView = itemView.findViewById(R.id.mesajTextView) as TextView
    val timeNewsTextView = itemView.findViewById(R.id.timeNewsTextView) as TextView
}
}

My fragment where ReyclerView is populated:

 override fun onActivityCreated(savedInstanceState: Bundle?) {

      newsRecyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
   }




  private fun populalteQuestionsList() {
        val mChatDatabaseReference = FirebaseDatabase.getInstance().reference.child(Constants.NEWS)
        mListenerPopulateList = mChatDatabaseReference.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                for (convSnapshot in dataSnapshot.children) {
                    val  news = ArrayList<News>()
                    val conv = convSnapshot.getValue(News::class.java)
                    news.add(conv!!)
                    val adapter = NewsList(news)
                    newsRecyclerView!!.adapter = adapter
                    adapter.notifyDataSetChanged()
                }
            }
            override fun onCancelled(databaseError: DatabaseError) {

            }
        })
        mChatDatabaseReference.addListenerForSingleValueEvent(mListenerPopulateList)
    }

Layout for items:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        card_view:cardCornerRadius="2dp"
        card_view:contentPadding="10dp"
        card_view:cardElevation="10dp">

        <RelativeLayout
            android:id="@+id/relativeLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="10dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="10dp">

            <TextView
                android:id="@+id/mesajTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:layout_alignParentTop="true"
                android:layout_marginStart="64dp"
                android:textAppearance="?android:attr/textAppearanceLarge"
                tools:text="Mesaj" />

            <TextView
                android:id="@+id/timeNewsTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_marginEnd="16dp"
                android:layout_marginTop="4dp"
                android:maxLength="15"
                android:maxLines="1"
                android:textAppearance="?android:attr/textAppearanceSmall"
                tools:text="14:20" />
        </RelativeLayout>

    </android.support.v7.widget.CardView>
</LinearLayout>

Hope you understand, please help me I really need to finish this app.

回答1:

You're recreating the dataset at every iteration, so it will always have the last added item, move the instantiation of the datasource to outside the loop. Also, try not adding the values for the adapter at every iteration. When you're done adding items to the datasource, then you should add them to the adapter and set the adapter in the recyclerview. :

val  news = ArrayList<News>()
for (convSnapshot in dataSnapshot.children) {
     val conv = convSnapshot.getValue(News::class.java)
     news.add(conv!!)
}
val adapter = NewsList(news)
newsRecyclerView!!.adapter = adapter
adapter.notifyDataSetChanged()


回答2:

You are creating new list with having single element in loop and passing it to adapter so it has only one element to show so

Move this outside loop

 val adapter = NewsList(news)
 newsRecyclerView!!.adapter = adapter
 adapter.notifyDataSetChanged()

and initialise list outside for loop


 val  news = ArrayList<News>()
 for (convSnapshot in dataSnapshot.children) {
     val conv = convSnapshot.getValue(News::class.java)
     news.add(conv!!)
  }
 val adapter = NewsList(news)
 newsRecyclerView!!.adapter = adapter
 adapter.notifyDataSetChanged()

Note : fill_parent has been deprecated so us match_parent