BRDroid
BRDroid

Reputation: 4388

Recycler view is not populated with data

I have a recycler view and I am passing data to the recyclerviewadapter but recycler view does not show any data.

ProdyctsRecyclerViewAdapter - it is getting the data in setList but does not display it

Where am I doing it wrong please

Thanks R

class ProductsRecyclerViewAdapter(private val clickListener: (Product) -> Unit): RecyclerView.Adapter<ProductsMyViewHolder>() {

    private val productsList = ArrayList<Product>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductsMyViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val binding: ListItemBinding =
            DataBindingUtil.inflate(layoutInflater, R.layout.products_list_item, parent, false)

        return ProductsMyViewHolder(binding)
    }

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

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

    fun setList(products: List<Product>) {
        productsList.clear()
        productsList.addAll(products)
    }
}

class ProductsMyViewHolder(val binding: ListItemBinding): RecyclerView.ViewHolder(binding.root) {

    fun bind(product: Product, clickListener: (Product) -> Unit) {
        binding.nameTextView.text = product.name
        binding.emailTextView.text = product.catagory
        binding.listItemLayout.setOnClickListener {
            clickListener(product)
        }
    }
}

ProductsFragment

class ProductsFragment: Fragment() {
    private lateinit var binding: ProductsBinding
    private lateinit var navController: NavController
    private lateinit var productsViewModel: ProductsViewModel
    private lateinit var adapter: ProductsRecyclerViewAdapter


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding =  DataBindingUtil.inflate(inflater, R.layout.products, container, false)
        val dao = SubscriberDatabase.getInstance(requireActivity().applicationContext).productDAO
        val repository = ProductRepository(dao)
        val factory = ProductsViewModelFactory(repository, requireActivity().applicationContext)
        productsViewModel = ViewModelProvider(this, factory).get(ProductsViewModel::class.java)
        binding.productsViewModel = productsViewModel
        binding.lifecycleOwner = this
        val view = binding.root

        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        navController = Navigation.findNavController(view)
        initRecyclerView()
        productsViewModel.navigateScreen.observe(viewLifecycleOwner, EventObserver {
            navController.navigate(it)
        })
    }

    private fun initRecyclerView() {
        binding.productsRecyclerView.layoutManager = LinearLayoutManager(context)
        adapter = ProductsRecyclerViewAdapter ({ selectedItem: Product -> listItemClicked(selectedItem)})
        displayProductssList()
    }

    private fun displayProductssList() {
        productsViewModel.products.observe(viewLifecycleOwner, Observer {
            Log.i("MYTAG", it.toString())
            adapter.setList(it)
            adapter.notifyDataSetChanged()
        })
    }

    private fun listItemClicked(product: Product) {
        Toast.makeText(context, "Selected name is ${product.name}", Toast.LENGTH_LONG).show()
        //productsViewModel.initUpdateAndDelete(subscriber)
    }
}

ProductsViewModel

class ProductsViewModel (
    private val repository: ProductRepository,
    private val context: Context
): ViewModel() {

    val products = repository.products
}

Products_list_item

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:orientation="vertical">

        <androidx.cardview.widget.CardView
            android:id="@+id/card_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:clickable="true"
            android:focusable="true"
            app:cardBackgroundColor="@color/colorPrimary"
            app:cardCornerRadius="10dp"
            app:cardElevation="10dp" >

            <LinearLayout
                android:id="@+id/product_list_item_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/product_name_text_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    android:text="name"
                    android:textColor="#FFFFFF"
                    android:textSize="30sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/product_catagory_text_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    android:text="catagory"
                    android:textColor="#FFFFFF"
                    android:textSize="24sp"
                    android:textStyle="bold" />
            </LinearLayout>
        </androidx.cardview.widget.CardView>
    </LinearLayout>
</layout>

Thank you Parag Pawar for the answer For reference made the followingn changes

 private fun initRecyclerView() {
        binding.productsRecyclerView.layoutManager = LinearLayoutManager(context)
        adapter = ProductsRecyclerViewAdapter ({ selectedItem: Product -> listItemClicked(selectedItem)})
        binding.productsRecyclerView.adapter = adapter //ADDED THIS LINE
        displayProductssList()
    }

In productsRecyclerView, had the wrong binding it should be ProductsListItemBinding

    val binding: ProductsListItemBinding =
        DataBindingUtil.inflate(layoutInflater, R.layout.products_list_item, parent, false)

ProductsMyViewHolder(val binding: ProductsListItemBinding):

Upvotes: 0

Views: 299

Answers (3)

Parag Pawar
Parag Pawar

Reputation: 857

You've not set the adapter to recycler view. In your initRecyclerView() set the adapter after initializing it.

private fun initRecyclerView() {
    binding.productsRecyclerView.layoutManager = LinearLayoutManager(context)
    adapter = ProductsRecyclerViewAdapter ({ selectedItem: Product -> listItemClicked(selectedItem)})
    
    //notice this
    binding.productsRecyclerView.adapter = adapter

    displayProductssList()
}

Upvotes: 2

Rajnish Sharma
Rajnish Sharma

Reputation: 388

I don't understand why are you clearing your list and adding them at the same time.

fun setList(products: List<Product>) {
    productsList.clear()
    productsList.addAll(products)
}

if you want to first clear your list you should do it outside the loop

Upvotes: 0

vicomo500
vicomo500

Reputation: 1

add notifyDataSetChanged() method in your Adapter's setList() method

Upvotes: 0

Related Questions