尽管官方对RecycleView的api封装得很好,但是作为一个懒惰的程序员,能少写代码就少些写代码,一劳永逸的事太有吸引力了。
1、定义一个接口,接口主要有两个用途,第一是获取ViewHolder,第二是初始化界面,这样定义是为了抽象出通用的操作,至于个性化的东西通过接口实现就好
import android.support.v7.widget.RecyclerView;
public interface HolderHelper {
RecyclerView.ViewHolder getHolder();
void setup(T holder,K data);
}
2、CommonAdapter 包装一下官方的api,尽量让通用的操作在这里执行
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
import okhttp.example.com.okhttptest.activity.weiget.listview.listitem.HolderHelper;
public class CommonAdapter extends RecyclerView.Adapter {
private int layoutId;
private List mData;
public CommonAdapter(int itemId, List data) {
layoutId = itemId;
mData = data;
}
@NonNull
@Override
public T onCreateViewHolder(@NonNull ViewGroup parent, int i) {
View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
HolderHelper helper = (HolderHelper) view;//根据T类型来初始化viewholder
return (T) helper.getHolder();
}
@Override
public void onBindViewHolder(@NonNull T holder, int i) {
HolderHelper helper = (HolderHelper) holder.itemView;//绑定ui和数据,通用操作,具体通过setup方法执行
helper.setup(holder, mData.get(i));
}
@Override
public int getItemCount() {
return mData.size();//列表的长度
}
}
3、创建布局文件和类文件,并让布局文件的跟目录指向改类文件
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:padding="15dp"
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/image"/>
public class ListItem extends RelativeLayout implements HolderHelper {
public ListItem(Context context) {
super(context);
}
public ListItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setup(MyViewHolder holder, BeanInfo.Bean bean) {
//TODO 初始化界面
holder.contentView.setText(bean.content);
}
@Override
public RecyclerView.ViewHolder getHolder() {
return new MyViewHolder(this);
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView contentView;
public MyViewHolder(View itemView) {
super(itemView);
contentView = itemView.findViewById(R.id.text);
}
}
}
4、前期工作都准备好了,开始调用封装好的CommonAdapter,前方高能
mRecyclerView = findViewById(R.id.recyclelistview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new CommonAdapter(R.layout.item, mList);
mRecyclerView.setAdapter(mAdapter);
只需实例化CommonAdapter,传入item的布局文件和数据集合就可以了,adapter内部如何处理数据过程不用去关心,项目开发中频繁修改的是item的UI部分
所以在ListItem中的setup方法修改即可,同时要在自定义的ViewHolder中注册用到的控件。
需要注意的地方是,实现HolderHelper的是否,需要传入两个泛型,分别是ViewHolder和数据模型,不要搞混淆了。
当然以上可以满足单纯的列表展示的功能,复杂一点的,例如排序,布局刷新的功能,就需要通过继承CommonAdapter来实现了。例如我想给每个item加个点击效果,当然这个可以通过setup来改,现在只做继承CommonAdapter的展示
class MyAdapter extends CommonAdapter{
public MyAdapter(int itemId, List data) {
super(itemId, data);
}
@Override
public void onBindViewHolder(@NonNull ListItem.MyViewHolder holder, int i) {
super.onBindViewHolder(holder, i);
holder.itemView.setBackgroundResource(R.drawable.clickable_item_bg_selector);
holder.itemView.setClickable(true);
}
}
引用
mAdapter = new MyAdapter(R.layout.item, mList);
以上封装兼顾了简约和可扩展。