![](/img/trans.png)
[英]Android Stop recycler-View adapter binding data for already shown items
[英]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.