Yarin Shitrit
Yarin Shitrit

Reputation: 327

RecyclerView with ListAdapter

i am trying to transform my Adapter to ListAdapter in order to include the Paging library in future. My app is a basic 2 fragments notes app that the first fragment has the recycler view and the second fragment has an EditText to insert text to the recycler view. I have implemented everything and for some reason my recyclerview does not display anything after submitList() is called.. I observe my livedata list with my adapter list and my livedata list is getting data from a room database that i query data into it. before i transformed my Adapter to ListAdapter everything worked fine

any suggestions?

my Adapter class :

package com.example.mvvm_example

import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.mvvm_example.db.Word

interface OnItemClickListener : View.OnClickListener {
    override fun onClick(v: View?) {
    }
}

class ListAdapterCallBack : DiffUtil.ItemCallback<Word>() {
    override fun areItemsTheSame(oldItem: Word, newItem: Word): Boolean {
        return oldItem.mWord == newItem.mWord
    }

    override fun areContentsTheSame(oldItem: Word, newItem: Word): Boolean {
        return oldItem == newItem
    }
}

class WordAdapter(
    private val context: Context,
    private val onItemClickListener: OnItemClickListener
) :
    ListAdapter<Word, WordAdapter.WordViewHolder>(ListAdapterCallBack()) {
    private var wordList = listOf<Word>()

    class WordViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
        private val textView = view.findViewById<TextView>(R.id.textView)!!

        fun onBind(listener: OnItemClickListener, word: Word) {
            textView.text = word.getmWord()
            view.setOnClickListener {
                listener.onClick(view)
            }
        }
    }

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

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

    fun setWords(list: MutableList<Word>) {
        wordList = list
        notifyDataSetChanged()
    }

    override fun submitList(list: MutableList<Word>?) {
        Log.d("Adapter", "list sumbitted list is ${list.toString()}")
        super.submitList(list?.let { ArrayList(it) })
    }

    override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
        val word = wordList[position]
        holder.onBind(onItemClickListener, word)

    }
}

my first fragment which holds the recyclerview :

package com.example.mvvm_example

import android.app.Activity
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.mvvm_example.db.Word
import kotlinx.android.synthetic.main.fragment_first.*

private const val TAG = "firstFrag"

class FirstFragment : Fragment() {
    private lateinit var viewModel: AppViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        Log.d(TAG, "onCreateView called")
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        Log.d(TAG, "onActivityCreated called")
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this).get(AppViewModel::class.java)

        val recyclerView = requireActivity().findViewById<RecyclerView>(R.id.recyclerview)
        val adapter =
            WordAdapter(requireActivity().applicationContext, object : OnItemClickListener {
                override fun onClick(v: View?) {
                    super.onClick(v)
                    Toast.makeText(
                        requireActivity().applicationContext,
                        "item clicked",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            })

        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(requireContext())
        viewModel.getAllWords().observe(requireActivity(), Observer {
            adapter.submitList(it)
        })
        fab.setOnClickListener {
            findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
        }

        delfab.setOnClickListener {
            viewModel.deleteAllWords()
            Toast.makeText(requireContext(), "Words Deleted", Toast.LENGTH_LONG).show()
        }

    }
}

my Word data class :

package com.example.mvvm_example.db

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.jetbrains.annotations.NotNull


@Entity(tableName = "word_table")
data class Word(

    @ColumnInfo(name = "word")
    @PrimaryKey
    @NotNull
     val mWord: String
) {


    fun getmWord() = mWord
}

EDIT if i switch adapter.submitList(it) with adapter.setWords(it) it also works.. so it has to be something wrong with that submitList() method

Upvotes: 2

Views: 5574

Answers (1)

C&#244;ng Hải
C&#244;ng Hải

Reputation: 5241

If you using ListAdapter it means it manage list item in itself. You should remove your wordList inside and method getItemCount. For access data only call getItem(position) method. No need override method submitList

Upvotes: 6

Related Questions