繁体   English   中英

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

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

我在做什么:我已经使用数据绑定显示了列表视图

我想要找到的是:如何正确添加点击事件并将吐司显示为学生姓名

学生.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

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

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


}

有几种方法可以做到。 当我希望回收器视图上的项目可点击时,我会这样做。

首先我创建一个界面

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

其次,在视图持有者类上,我添加了这些方法

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

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

最后在 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);
        }
    });
}

如果您希望我提供适配器的所有代码,请询问。

我使用了以下方法。 请注意,如果您愿意,您的“项目”可以是您的视图模型,您可以访问每个项目的绑定布局内部。 从那里你可以在 vm 中调用你想要的任何方法,或者设置一个 LiveData 或任何告诉视图显示 toast 的方法。 我建议为此目的使用SingleLiveEvent

首先,我创建了一个 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));
}

}

此适配器使用以下 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();
}
}

然后你通过子类化 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);
    }
}
}

其中 Model 是一个带有一些字段的简单 java 对象类(为简洁起见,不包括在内)。

然后是显示实际模型并允许数据绑定的布局。

<?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>

    ....

然后您可以简单地在布局内使用该项目。

奖金使用示例

然后根据需要实例化它。 我的建议,我是如何做到的,是在视图(片段)中实例化使用数据绑定附加它。

<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" />

使用以下@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM