What is the right way of Android View Binding in the RecyclerView adapter class?

前端 未结 5 1480
[愿得一人]
[愿得一人] 2021-02-14 07:08

Here is the code I used in my RecycleView adapter class. I don\'t know this is the right way or not to use View Binding. If you have a better solution answer me. Th

相关标签:
5条回答
  • 2021-02-14 07:47

    Here is full recycler view adapter class in java :

    public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.MyViewHolder> {
    
        private List<Note> notes;
        private ItemNotesBinding notesBinding;
    
        public NotesAdapter(List<Note> notes) {
            this.notes = notes;
        }
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        
            notesBinding = ItemNotesBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
            return new MyViewHolder(notesBinding);
        }
    
        @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    
            Note note = notes.get(position);
            notesBinding.tvTitle.setText(note.getNote());
        }
    
        @Override
        public int getItemCount() {
            return notes.size();
        }
    
        public static class MyViewHolder extends RecyclerView.ViewHolder {
    
            ItemNotesBinding notesBinding;
    
            public MyViewHolder(@NonNull ItemNotesBinding binding) {
                super(binding.getRoot());
                notesBinding = binding;
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-14 07:48

    What you need to do is pass the generated binding class object to the holder class constructor. In your example, You have common_circle_image XML file for RecyclerView item and the generated class is CommonCircleImageBinding so like this you use the onCreateViewHolder to pass the generated binding class to the ViewHolder class

    @NonNull
    @Override
    public CategoryAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        CommonCircleImageBinding itemBinding = CommonCircleImageBinding .inflate(LayoutInflater.from(parent.getContext()), parent, false);
        return new MyViewHolder(itemBinding);
    }
    

    and use the holder class like this so you can use these fields in onBindViewHolder

    static class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView txt;
        private ImageView img; 
    
        MyViewHolder(CommonCircleImageBinding itemBinding) {
            super(itemBinding.getRoot());
            img = itemBinding.img ;
            txt = itemBinding.txt ;
        }
    }
    
    0 讨论(0)
  • 2021-02-14 07:59

    You can create CommonCircleImageBinding directly in onCreateViewHolder by CommonCircleImageBinding.inflate(LayoutInflater.from(parent.getContext()))

    Then pass it to MyViewHolder

    0 讨论(0)
  • 2021-02-14 08:03

    Here is full view binding recycler view code in java, you can do as like:

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-14 08:12

    For the folks looking for a solution in Kotlin, here it is:

    It's a minimal example, where the adapter gets an array of Strings and displays each of the them in a layout called recyclerview_item in a TextView called itemTextView.

    It's based on @SomeshKumar's answer and answers @Vijay Villiers question on how to get rid of the private TextView txt;

    Edit: New Version: I noticed the generated ...Binding has a .bind() function, so let's use it. (I guess it might be less resource-heavy?)

    class SampleAdapter(private val context: Context, private val content: Array<String>) :
            RecyclerView.Adapter<SampleAdapter.CustomViewHolder>()
    {
        class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view)
    
        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int) =
                CustomViewHolder(
                        // Alternatively inflate like usual, if you don't need binding
                        RecyclerviewItemBinding
                                .inflate(LayoutInflater.from(context), viewGroup, false)
                                .root
                )
    
        override fun getItemCount() = content.size
    
        override fun onBindViewHolder(viewHolder: CustomViewHolder, position: Int)
        {
            RecyclerviewItemBinding.bind(viewHolder.itemView).apply{
                itemTextView.text = content[position]
                
            }
        }
    } 
    

    Edit: Old Version:

    class SampleAdapter(private val context: Context, private val content: Array<String>) :
            RecyclerView.Adapter<SampleAdapter.CustomViewHolder>()
    {
        class CustomViewHolder(var viewBinding: RecyclerviewItemBinding) :
                RecyclerView.ViewHolder(viewBinding.root)
    
        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int) =
                CustomViewHolder(
                        RecyclerviewItemBinding
                                .inflate(LayoutInflater.from(context), viewGroup, false)
                )
    
        override fun getItemCount() = content.size
    
        override fun onBindViewHolder(viewHolder: CustomViewHolder, position: Int)
        {
            viewHolder.viewBinding.apply {
                itemTextView.text = content[position]
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题