26

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.

Mayur Misal
  • 806
  • 10
  • 13
M D P
  • 4,525
  • 2
  • 23
  • 35

4 Answers4

31

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();
        }
    }

}
M D P
  • 4,525
  • 2
  • 23
  • 35
  • 2
    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.getContext()), parent, false); – Yash Aug 28 '20 at 15:32
  • 2
    @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`. – M D P Aug 31 '20 at 00:51
  • Or use `parent.context.getLayoutInflater()`? – Ben Butterworth Mar 11 '21 at 16:47
  • 1
    LayoutInflator layoutInflator = LayoutInflator.from(parent.getContext()); – Sivakumar Sep 06 '21 at 14:46
12
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

Amit pandey
  • 1,149
  • 1
  • 4
  • 15
6

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;
        }
    }
}
Mayur Misal
  • 806
  • 10
  • 13
  • 1
    This examples `onCreateViewHolder` is the one that inflates rows correctly - accepted answers way generated empty rows. – Starwave Jun 11 '21 at 10:53
1

Here is full adapter code by using ViewBinding

public class JobsAdapter2 extends RecyclerView.Adapter<JobsAdapter2.ViewHolder> {

    public ArrayList<JobsList> jobsList;

    LayoutTitleItem2Binding binding;

    public JobsAdapter2(ArrayList<JobsList> jobsList) {
        this.jobsList = jobsList;
    }

    public int getCount() {
        return jobsList.size();
    }

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

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        JobsList dataModel = jobsList.get(position);
        Context context = binding.getRoot().getContext();
        Activity activity = (Activity) context;

        binding.date.setText(dataModel.getTime())

    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(LayoutTitleItem2Binding itemView) {
            super(itemView.getRoot());
            binding = itemView;

        }
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Anas Lakhani
  • 29
  • 1
  • 4