作为一个初学者,接触RecyclerView已经有了一年多的时间了,虽然比ListView一些方面要显得麻烦,但可以实现的功能也更加多样,感觉真的很强大和实用,在这里总结一下常用的使用。
RecyclerView的核心就是回收和复用view。所以首先我们理清思路就是创建一个可以复用的view item,然后利用复用机制在我们想添加列表的位置复用view就好。
由于现在Androidx的引入,统一了v4,v7库,所以不在需要纠结是哪个包下的了,只用关系方法名就好了,其使用方法也和原来基本一致
implementation 'androidx.recyclerview:recyclerview:1.0.0'
接着就是在需要添加列表的地方添加控件
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
然后因为重点在于复用,所以我们需要建立最小的item样式,新建一个xml布局文件,因为作为案例所以我们就做最简单的样式,在这里很容易有一个错误就是把高写成了match,这样的结果就会导致最后显示感觉只有一个item,然后往下翻会发现还有,就是因为这里没注意写错了
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/item_num"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
然后需要建立一个adapter来适配这个item
在这个adapter中我们需要创建一个继承至RecyclerView.ViewHolder的ViewHolder成员内部类,用做的是来绑定item中的控件,然后还需要一个带参的构造方法,来实例化主activity传过来的数据,这里可以有context和list;然后需要重写RecyclerView.Adapter中的三个方法,其中onCreateViewHolder顾名思义就是创造时候的绑定的,主要是用做返回一个viewHolder对象,着里面的context对象可以用viewGroup.getContext(),也是和之前传入的是一样的。onBindViewHolder中需要的是实现对绑定的控件的一些监听和传入复用给view的值,getItemCount方法返回list的长度;
public class NumAdapter extends RecyclerView.Adapter<NumAdapter.ViewHolder> {
private Context mContext;
private List<String> mList;
public NumAdapter(Context context, List<String> list){
mContext = context;
mList = list;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.list_item,viewGroup,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, int i) {
viewHolder.mTextView.setText(mList.get(i));
viewHolder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getLayoutPosition();
Toast.makeText(mContext,mList.get(pos),Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
View mView;
TextView mTextView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mView = itemView;
mTextView = (TextView)itemView.findViewById(R.id.item_num);
}
}
}
最后就是在activity中确定item显示的位置,分割以及删除的动画,分割线现在没特殊要求不用去自定义,可以直接引用就行,已经在库里带有了
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.items);
NumAdapter adapter = new NumAdapter(this,mList);
// 添加布局管理
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
recyclerView.setAdapter(adapter);
// 添加分割线
recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.HORIZONTAL));
最后实现的效果,此处添加的都是默认的分割线,中间竖线颜色更深是因为被多次去画了这个分割线
这里的点击响应也可以采用回调的方式去写
public interface OnItemClickListener{
void onItemClick(Everyday everyday);
}
public void SetItemClickListener(OnItemClickListener onItemClickListener){
mOnItemClickListener = onItemClickListener;
}
然后在activity中调用
adapter.SetItemClickListener
方法传入OnItemClickListener就可以,这样的写法可以使在activity中就可以看清后面点击之后的逻辑而不用去关心其中的实现的具体细节