前言
起初学习 Android 的时候,为了兼容低版本的安卓(不是有兼容包吗?摔!),在学习列表的时候,选择了 ListView 而跳过了 RecyclerView。最近项目需要增加新功能模块,于是动起了在该功能中用 RecyclerView 替代 ListView 的念头。
关于 RecyclerView 的总结,有时间我一定补上(咕咕)...... 这里先记录一下使用中遇到的问题及我的一些心得体会。
RecyclerView点击事件
这里主要介绍的是 郭霖 在《第一行代码 第二版》中使用的方法,及参考网上的一些改进方法。
创建ItemView时添加点击事件
即在 RecyclerView 的 Adapter类 中:onCreateViewHolder()中可以取得 Item 及 Item内子控件,那么我们可以在此处设置监听。
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.ate_recyclerview_item, parent, false);
final ViewHolder holder = new ViewHolder(view,mOnItemClickListener);
holder.ItemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
ATE_RecyclerviewItem_Data ate = mATEList.get(position);
Toast.makeText(view.getContext(), "你点击了View"+ ate.getName(), Toast.LENGTH_SHORT).show();
}
});
holder.ateEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//...
}
});
return holder;
}
这种方法实现起来很简单,但是我们的逻辑需要写在 Adapter 中,耦合严重。
改进:通过接口实现点击事件
RecyclerView 的 Adapter类
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener {
void onButtonClicked(View view, int position,String input_str);
}
public void setOnItemClickListener(OnItemClickListener clickListener) {
this.mOnItemClickListener = clickListener;
}
//...
static class ViewHolder extends RecyclerView.ViewHolder{
View ItemView;
TextView ateName;
EditText ateEdit;
Button ateButton;
public ViewHolder(View view, final OnItemClickListener onClickListener) {
super(view);
ItemView = view;
ateName = view.findViewById(R.id.ate_name);
ateEdit = view.findViewById(R.id.ate_edit);
ateButton = view.findViewById(R.id.ate_button);
ateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (onClickListener != null) {
int position = getAdapterPosition();
//确保position值有效
if (position != RecyclerView.NO_POSITION) {
onClickListener.onButtonClicked(view, position,,ateEdit.getText().toString());
}
}
}
});
}
}
//...
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.ate_recyclerview_item, parent, false);
final ViewHolder holder = new ViewHolder(view,mOnItemClickListener);
return holder;
}
这里我们在 ViewHolder 中设置了子控件 Button 的点击事件,而点击事件的处理方法是接口 OnItemClickListener()的onButtonClicked()。
这一接口必须在外部实现,于是我们对外暴露了 setOnItemClickListener()方法。
接下来需要解决的问题是,ViewHolder是静态内部类,我们如何在 ViewHolder 中取得 OnItemClickListener()呢?
这里使用的方法是在 onCreateViewHolder()中 创建 ViewHolder 时进行传参。
外部使用时,仅需要
adapter.setOnItemClickListener(new ATEAdapter.OnItemClickListener() {
@Override
public void onButtonClicked(View view, int position, String input_str) {
Toast.makeText(getActivity(),position+":"+ input_str,Toast.LENGTH_SHORT).show();
}
});
效果(这里仅截取了部分)