如何通过 RecyclerView 使用 Android 视图绑定

Posted

技术标签:

【中文标题】如何通过 RecyclerView 使用 Android 视图绑定【英文标题】:How to use Android View Binding with RecyclerView 【发布时间】:2020-06-04 09:52:55 【问题描述】:

这不是数据绑定,这是 android Studio 3.6 Canary 11+ 中的新视图绑定,描述为here。

对于在 Activity 中使用,很明显,您只需像这样使用它:

假设我们有一个名为activity_main.xml的布局

那么在代码中我们可以这样使用:

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如何使用View Binding?

编辑:请用Java解释。

【问题讨论】:

【参考方案1】:

假设我们在 activity_main.xml 中有一个 RecyclerView,它的 id 是 "@+id/rv_test"

在 Activity 内部我们可以这样使用它:

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

让我们将 RecyclerView 项目的布局命名为 test_list_item.xml

然后我们可以像这样在 Activity 中实现我们的适配器:

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


【讨论】:

在您的代码中, binding = ActivityMainBinding.inflate(getLayoutInflater());我不能添加 getLayoutInflator() 作为参数。它向我显示了一个错误。应该是,binding = ActivityMainBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); @Yash 此代码假定您在 Activity 中实现 AdaptergetLayoutInflater() 来自 Activity 类。如果您的适配器不在上下文中,那么您需要为LayoutInflater.from 提供源上下文。 或者使用parent.context.getLayoutInflater()? LayoutInflator layoutInflator = LayoutInflator.from(parent.getContext());【参考方案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()
        
    



只需将模型或数组列表传递给适配器并在绑定视图中设置

【讨论】:

【参考方案3】:

这是使用视图绑定的完整适配器代码,您可以这样做。

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;
        
    

【讨论】:

这个例子onCreateViewHolder 是正确膨胀行的例子 - 接受的答案方式生成空行。【参考方案4】:

这是使用 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;

        
    

【讨论】:

嗨!你能提供一些关于你所做的事情的见解吗?干杯!

以上是关于如何通过 RecyclerView 使用 Android 视图绑定的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 RecyclerView 使用 Android 视图绑定

如何通过firebase实时数据库永久隐藏RecyclerView中的imageview

如何使用卡片创建水平滚动 RecyclerView

如何通过单击 recyclerview 中的项目来打开新活动 [重复]

如何实现android的垂直滑动视图UI

如何通过 Volley 获取数据实现具有两个或多个不同卡片视图的 RecyclerView?