简体   繁体   English

单击行时的回收站视图数据绑定

[英]Recycler-view data binding on click of row

What I am doing : I have displayed the list view using data binding我在做什么:我已经使用数据绑定显示了列表视图

What I am trying to find : How to properly add a on click event and display a toast as student name我想要找到的是:如何正确添加点击事件并将吐司显示为学生姓名

Student.java学生.java

public class Student {

    private  String name;
    private  String email;

    public Student() {
    }

    public Student(String name, String email) {
        this.name = name;
        this.email = email;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }


}

ActDemoListView.java ActDemoListView.java

public class ActDemoListView extends AppCompatActivity {


    private ActDemoListViewViewModel actDemoListViewViewModel;
    private ActDemoListViewBinding actDemoListViewBinding;


    private RecyclerView recyclerView;
    private AdptStudent adptStudent;
    private List<Student> studentList = new ArrayList<>();

    /************************************* Life Cycle Methods *************************************/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initOnCreate();
    }
    /************************************* Life Cycle Methods *************************************/

    /************************************* Init Methods *******************************************/
    /** Init OnCreate **/
    private void initOnCreate() {
        setContentView(R.layout.act_two_way_display_data);
        //Connect the view model to activity
        connectViewModel();
        //Bind the layout to activity
        bindLayoutToActivity();

        recyclerView = actDemoListViewBinding.recyclerList;
        adptStudent = new AdptStudent(studentList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(adptStudent);

        prepareMovieData();
    }



    /************************************* Init Methods *******************************************/


    private void connectViewModel() {
        actDemoListViewViewModel = ViewModelProviders.of(this).get(ActDemoListViewViewModel.class);
    }

    private void bindLayoutToActivity() {
        actDemoListViewBinding = DataBindingUtil.setContentView(this,R.layout.act_demo_list_view);
    }

    private void prepareMovieData() {
        Student movie = new Student("Shruthi", "user11@google.com");
        studentList.add(movie);

        movie = new Student("Shalvi", "user1@google.com");
        studentList.add(movie);

        movie = new Student("Pavan", "user2@google.com");
        studentList.add(movie);

        movie = new Student("Brijesh", "user3@google.com");
        studentList.add(movie);

        movie = new Student("Anudeep", "user4@google.com");
        studentList.add(movie);

        adptStudent.notifyDataSetChanged();
    }

}

AdptStudent.java AdptStudent.java

public class AdptStudent extends RecyclerView.Adapter<AdptStudent.MyViewHolder> {


    private List<Student> studentsList = new ArrayList<>();


    public AdptStudent(List<Student> studentsList) {
        this.studentsList = studentsList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ListItemBinding listItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),R.layout.list_item, parent, false);
        return new MyViewHolder(listItemBinding);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Student student = studentsList.get(position);
        holder.listItemBinding.setStudent(student);
    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder {

        private ListItemBinding listItemBinding;

        public MyViewHolder(ListItemBinding ListItemBinding) {
            super(ListItemBinding.getRoot());
            this.listItemBinding=ListItemBinding;
        }
    }


}

There are several ways to do it.有几种方法可以做到。 When i want an item on a recycler view to be clickable i do this.当我希望回收器视图上的项目可点击时,我会这样做。

Firstly i create an interface首先我创建一个界面

public interface ItemClickListener {
    void onClick(View view, int position, boolean click);
}

Secondly, on the view holder class i add these methods其次,在视图持有者类上,我添加了这些方法

    @Override
    public void onClick(View view) {
        itemClickListener.onClick(view, getAdapterPosition(), false);
    }

    public void setItemClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

And lastly on the onBindViewHolder最后在 onBindViewHolder

@Override
public void onBindViewHolder(@NonNull final CategoryAdapter.MyViewHolder myViewHolder, int i) {

    myViewHolder.setItemClickListener(new ItemClickListener() {
        @Override
        public void onClick(View view, int position, boolean click) {
            Intent intent = new Intent(myViewHolder.context, Myclass.class);
            myViewHolder.context.startActivity(intent);
        }
    });
}

If you want me to provide all the code for the adapter just ask.如果您希望我提供适配器的所有代码,请询问。

I have used the following approach.我使用了以下方法。 Note that your "Item" can be your viewmodel if you like which you have access to inside the bound layout for each item.请注意,如果您愿意,您的“项目”可以是您的视图模型,您可以访问每个项目的绑定布局内部。 And from there you can call whatever method you want inside the vm, or set a LiveData or whatever to tell the view to display the toast.从那里你可以在 vm 中调用你想要的任何方法,或者设置一个 LiveData 或任何告诉视图显示 toast 的方法。 I recomment to use SingleLiveEvent for this purpose.我建议为此目的使用SingleLiveEvent

First I created a BaseAdapter.首先,我创建了一个 BaseAdapter。

public class BaseAdapter<T> extends ListAdapter<T, SingleItemViewHolder<T>> {

private final int variableId;

protected BaseAdapter(@NonNull DiffUtil.ItemCallback<T> diffCallback, int variableId) {
    super(diffCallback);
    this.variableId = variableId;
}

@NonNull
@Override
public SingleItemViewHolder<T> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    ViewDataBinding binding = DataBindingUtil.inflate(
            LayoutInflater.from(parent.getContext()), viewType, parent, false);

    return new SingleItemViewHolder<>(binding, variableId);
}

@Override
public void onBindViewHolder(@NonNull SingleItemViewHolder<T> holder, int position) {
    holder.bind(getItem(position));
}

} }

This adapter uses the following SingleItemViewHolder.此适配器使用以下 SingleItemViewHolder。

public final class SingleItemViewHolder<T> extends RecyclerView.ViewHolder {

private final ViewDataBinding binding;

private final int variableId;

/**
 * Constructor
 *
 * @param binding the binding to use
 * @param variableId variable to set on the binding
 */
public SingleItemViewHolder(ViewDataBinding binding, int variableId) {
    super(binding.getRoot());
    this.binding = Objects.requireNonNull(binding);
    this.variableId = variableId;
}

/**
 * Sets the data binding variable to the provided item
 * and calls {@link ViewDataBinding#executePendingBindings()}.
 *
 * @param item item to bind
 * @throws NullPointerException if item is null ({@code item == null})
 */
public void bind(@NonNull T item) {
    Objects.requireNonNull(item);
    binding.setVariable(variableId, item);
    binding.executePendingBindings();
}
}

Then you use it by subclassing the BaseAdapter and providing your own DiffCallback and layout like this.然后你通过子类化 BaseAdapter 并提供你自己的 DiffCallback 和这样的布局来使用它。

public final class ModelAdapter extends BaseAdapter<Model> {

public ModelAdapter() {
    super(new DiffCallback(), BR.item);
}

@Override
public int getItemViewType(int position) {
    return R.layout.item_model;
}

private static final class DiffCallback extends DiffUtil.ItemCallback<Model> {

    @Override
    public boolean areItemsTheSame(@NonNull Model oldItem, @NonNull Model newItem) {
        return oldItem.id.equals(newItem.id);
    }

    @Override
    public boolean areContentsTheSame(@NonNull Model oldItem, @NonNull Model newItem) {
        return oldItem.equals(newItem);
    }
}
}

Where Model is a simple java object class with some fields (not included for brevity).其中 Model 是一个带有一些字段的简单 java 对象类(为简洁起见,不包括在内)。

Then the layout which shows the actual model and allows for the data binding.然后是显示实际模型并允许数据绑定的布局。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="item"
            type="com.example.models.Model" />
    </data>

    ....

Then you can simply use that item inside the layout.然后您可以简单地在布局内使用该项目。

Bonus usage example奖金使用示例

Then instantiate it however you want.然后根据需要实例化它。 My recommendation, how I did it, was to instantiate in the view (fragment) the attach it using data binding.我的建议,我是如何做到的,是在视图(片段)中实例化使用数据绑定附加它。

<data>
    <variable
        name="adapter"
        type="com.example.ModelAdapter" />
</data>

....

<androidx.recyclerview.widget.RecyclerView
            recycler_view_base_adapter_items="@{vm.models}"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adapter="@{adapter}"
            android:orientation="vertical"
            android:scrollbars="vertical"             
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

With the following @BindingAdapter.使用以下@BindingAdapter。

@BindingAdapter(value = {"recycler_view_base_adapter_items"})
public static <T> void setRecyclerViewBaseAdapterItems(RecyclerView view,
                                                       @Nullable final List<T> items) {

    final RecyclerView.Adapter viewAdapter = view.getAdapter();

    if (viewAdapter == null || items == null) {
        Timber.w("recycler_view_base_adapter_items did nothing.");
        return;
    }

    try {
        @SuppressWarnings("unchecked") final BaseAdapter<T> adapter = (BaseAdapter<T>) viewAdapter;
        adapter.submitList(items);

    } catch (ClassCastException e) {
        Timber.e(e);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android 停止回收器-查看已显示项目的适配器绑定数据 - Android Stop recycler-View adapter binding data for already shown items 如何从Recycler-View适配器接收活动中的点击事件 - How to receive click event in activity from a recycler-view adapter 在活动中发送和添加回收者视图数据时遇到问题 - Getting a problem in sending and adding recycler-view data in an activity 为什么当点击它的项目时,adnroidx recycler-view 点击不起作用? - Why adnroidx recycler-view click not working when click it's item? 如何在 Recycler-view 中添加分区 - How to add section divider in Recycler-view 数据绑定Android Recycler视图 - Data Binding Android Recycler view 当我单击同一行的子视图时,为什么该行上的Recycler视图数据消失了? - Why is Recycler view data on the row is gone when i click on the same row's child view? Android多个水平回收站视图一起滚动 - Android multiple horizontal recycler-view scroll together 在Recycler-view onBindViewHolder中处理空值的最佳技巧是什么? - What is the best trick to handle null values in Recycler-view onBindViewHolder? 在Recycler-View Viewholder中以相同的布局使用不同的xml - Using different xml in same layouts in recycler-view viewholder
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM