How to use Android View Binding with RecyclerView

20,390

Solution 1

Let's say we have a RecyclerView inside activity_main.xml and its id is "@+id/rv_test"

Inside the Activity we can use it like so:

public class MainActivity extends Activity{

    ActivityMainBinding binding; //Name of the layout in camel case + "Binding"

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        binding.rvTest.setLayoutManager(layoutManager);
    }
}

Let's name the layout for RecyclerView items test_list_item.xml

Then we can implement our adapter inside Activity like this:

public class MainActivity extends Activity{

    ActivityMainBinding binding; //Name of the layout in camel case + "Binding"

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        binding.rvTest.setLayoutManager(layoutManager);

        List<String> items = Arrays.asList("item", "item", "item");

        binding.rvTest.setAdapter(new MyAdapter(items));
    }

    private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{

        private List<String> items;

        private class MyViewHolder extends RecyclerView.ViewHolder{

            TestListItemBinding binding;//Name of the test_list_item.xml in camel case + "Binding"

            public MyViewHolder(TestListItemBinding b){
                super(b.getRoot());
                binding = b;
            }
        }

        public MyAdapter(List<String> items){
            this.items = items;
        }

        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
            return new MyViewHolder(TestListItemBinding.inflate(getLayoutInflater()));
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position){
            String text = String.format(Locale.ENGLISH, "%s %d", items.get(position), position);

            //An example of how to use the bindings
            holder.binding.tvTest.setText(text);
        }

        @Override
        public int getItemCount(){
            return items.size();
        }
    }

}

Solution 2

class LanguageAdapter(val context: Context, var listData: MutableList<ListData>, val listener: onCheckListner) : RecyclerView.Adapter<LanguageAdapter.ViewHolder>() {

lateinit var bindind: LangugaeItemBinding

fun onRefresh(listData: MutableList<ListData>) {
    this.listData = listData
    notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    bindind = LangugaeItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)

    return ViewHolder(bindind)
}

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

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.setData(listData[position])

}

inner class ViewHolder(private val binding: LangugaeItemBinding) : RecyclerView.ViewHolder(binding.getRoot()), View.OnClickListener {
    override fun onClick(v: View?) {
        when (v) {
            itemView -> {

            }
        }
    }

    init {
        itemView.radio_button.setOnClickListener(this)
    }

    fun setData(model: ListData) {
        with(binding) {
            data = model
            executePendingBindings()
        }
    }

}
}

just pass the model or arraylist into adapter and set in binding view

Solution 3

Here is full adapter code by using view binding, you can do like this.

package com.jbws.myviewbindingdemo.adapter;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.jbws.myviewbindingdemo.databinding.RowXmlViewBinding;
import com.jbws.myviewbindingdemo.pojo.ModelObject;

import java.util.ArrayList;

public class RecyclerViewListAdapter extends RecyclerView.Adapter<RecyclerViewListAdapter.ViewHolder> {
    public ArrayList<ModelObject> modelObjectArrayList;

    public RecyclerViewListAdapter(ArrayList<ModelObject> modelObjectArrayList) {
        this.modelObjectArrayList = modelObjectArrayList;
    }

    @NonNull
    @Override
    public RecyclerViewListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(RowXmlViewBinding.inflate(LayoutInflater.from(parent.getContext()),
                parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewListAdapter.ViewHolder holder, final int position) {
        ModelObject modelObject = modelObjectArrayList.get(position);
        holder.rowXmlViewBinding.txtObjectName.setText(modelObject.getFullName());
        holder.rowXmlViewBinding.btnUpdateName.setOnClickListener(view -> {
         Log.i("LOG_TAG", "Full Name: " + modelObject.getFullName);
        });
    }

    @Override
    public int getItemCount() {
        return modelObjectArrayList == null ? 0 :
                modelObjectArrayList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private RowXmlViewBinding rowXmlViewBinding;

        public ViewHolder(RowXmlViewBinding rowXmlViewBinding) {
            super(rowXmlViewBinding.getRoot());
            this.rowXmlViewBinding = rowXmlViewBinding;
        }
    }
}
Share:
20,390

Related videos on Youtube

M D P
Author by

M D P

Updated on July 20, 2022

Comments

  • M D P
    M D P almost 2 years

    This is not data binding, this is View binding which is new to Android Studio 3.6 Canary 11+ described here.

    For using inside an Activity it is clear, you just use it like this:

    Let's say we have a layout named activity_main.xml

    Then in the code we can use it like this:

    public class MainActivity extends Activity{
    
        ActivityMainBinding binding; //Name of the layout in camel case + "Binding"
    
        @Override
        protected void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            binding = ActivityMainBinding.inflate(getLayoutInflater());
            setContentView(binding.getRoot());
        }
    }
    

    However, It's not clear how to use View Binding with RecyclerView?

    Edit: Please explain in Java.

  • Yash
    Yash over 3 years
    In your code, binding = ActivityMainBinding.inflate(getLayoutInflater()); I can not add getLayoutInflator() as parameter. It shows me an error. It should be, binding = ActivityMainBinding.inflate(LayoutInflater.from(parent.getCo‌​ntext()), parent, false);
  • M D P
    M D P over 3 years
    @Yash This code assumes that you are implementing your Adapter inside your Activity. getLayoutInflater() is from Activity class. If your adapter is not inside a Context then you need to provide the source Context for LayoutInflater.from.
  • zolastro
    zolastro about 3 years
    Hi! Could you provide some insight of what you've done? Cheers!
  • Ben Butterworth
    Ben Butterworth about 3 years
    Or use parent.context.getLayoutInflater()?
  • Starwave
    Starwave almost 3 years
    This examples onCreateViewHolder is the one that inflates rows correctly - accepted answers way generated empty rows.
  • Sivakumar
    Sivakumar over 2 years
    LayoutInflator layoutInflator = LayoutInflator.from(parent.getContext());