Saturday, 10 April 2021

RecyclerView skipping layout and lagging

I'm sorry to ask the repeatedly answered question but I just couldn't solve this relating to my specific case, maybe I'm missing something. The error is E/RecyclerView: No adapter attached; skipping layout and I'm not sure, is the problem with an adapter I set or the RecyclerView per se? Also, I was following a tutorial and this was the code that was presented.

(I tried brining the initRecyclerView() into the main onCreateView but no luck. Some answers say to set an empty adapter first and notify it with the changes later but I don't know how to do that.) This is my HomeFragment:

open class HomeFragment() : Fragment() {
    private lateinit var homeViewModel: HomeViewModel
    private lateinit var binding: FragmentHomeBinding

    private val language = arrayOf("English", "German", "Arabic", "Spanish", "Chinese", "French")


    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)

        val dao = VocabData.getInstance(this).VocabDao
        val repository = VocabRepository(dao)
        val factory = HomeViewModelFactory(repository, application = activity?.applicationContext as Application)
        homeViewModel = ViewModelProvider(this, factory).get(HomeViewModel::class.java)
        binding.myViewModel = homeViewModel
        binding.lifecycleOwner = this
        initRecyclerView()


        homeViewModel.message.observe(viewLifecycleOwner, Observer {
            it.getContentIfNotHandled()?.let {
                Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show()
            }
        })

        // create an adapter
        val arrayAdapter =
            ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, language)
        binding.spinner.adapter = arrayAdapter
        // Set layout to use when the list of choices appear
        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        // Set Adapter to Spinner
        binding.spinner.setAdapter(arrayAdapter)

        val button = binding.tagButton

        button.setOnClickListener{
        GlobalScope.launch(Dispatchers.IO) {
            homeViewModel.tagger(binding.spinner)
              }
        }

        return binding.root
    }

    private fun initRecyclerView(){
        binding.vocabRecyclerView.layoutManager = LinearLayoutManager(requireContext())
        displayVocabsList()
    }

    private fun displayVocabsList() {
    homeViewModel.vocabs.observe(viewLifecycleOwner, Observer {
        Log.i("MYTAG", it.toString())
        binding.vocabRecyclerView.adapter = MyRecyclerViewAdapter(it, { selectedItem: Vocab -> listItemClicked(selectedItem) })
    })

    }
    
    private fun listItemClicked(vocab: Vocab){
        Toast.makeText(requireContext(), "selected sentence is ${vocab.sentString}", Toast.LENGTH_LONG).show()
    }
}

And this is my RecyclerViewAdapter, which is really just boilerplate code:

class MyRecyclerViewAdapter(private val vocabsList: List<Vocab>, private val clickListener:(Vocab)->Unit) :
    RecyclerView.Adapter<MyViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val binding : ListItemBinding =
            DataBindingUtil.inflate(layoutInflater, R.layout.list_item, parent, false)
        return MyViewHolder(binding)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(vocabsList[position], clickListener)
    }

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

class MyViewHolder(private val binding: ListItemBinding):RecyclerView.ViewHolder(binding.root){
    fun bind(vocab: Vocab, clickListener:(Vocab)->Unit){
        binding.sentenceTextView.text = vocab.sentString
        binding.listItemLayout.setOnClickListener{
            clickListener(vocab)
        }
    }
}

I think that's all the related code. If you have an idea please let me know how to avoid this error/lag, thank you!



from RecyclerView skipping layout and lagging

No comments:

Post a Comment