Demo地址:https://github.com/Pedestrian0209/Adapter
RecycleView的好用不言而喻,但也不宜粗制滥造,反而加重了代码的重量。本文从RecyclerView.Adapter着手,寥寥数行代码,设计一款通用的Adapter,为大家提供一种思路。
RecyclerView.Adapter需要从两个方面入手,一个是RecyclerView.ViewHolder,一个是数据。一个Adapter可以适配不同的RecycleView列表,列表也会包含不同的类目item,就需要将RecyclerView.ViewHolder统一,以及拿到数据的共性即数据模型。
代码结构:
核心的类就是adapter目录下的三个类,bean目录下是我做测试用的数据类型,仅作参考。
数据模型
先看一下RecyclerView.Adapter默认需要实现的方法:
//根据每个item的类型返回不同的ViewHolder
@NonNull
@Override
public RecycleView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
return null;
}
//给ViewHolder绑定数据
@Override
public void onBindViewHolder(@NonNull RecycleView.ViewHolder viewHolder, int position) {
}
//获取列表item的数量
@Override
public int getItemCount() {
return 0;
}
//如果列表有多个item类目,则需要实现该方法,返回每个item的类型
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
假设每个item的类型是相同的,getItemViewType默认返回0即可,如果有多个类型,则需要为不同类型的item设置惟一的返回值。正常情况下不同类型的item,数据和布局都不相同,那将布局的id作为getItemViewType的返回值是最好的选择了,布局的id可以设计成从数据类型里面获取,使每种数据类型管理自己的布局id,即所有的数据类型都需要实现接口IRecycleViewData:
public interface IRecycleViewData {
//获取当前item的布局id
int getItemViewId();
}
对应的RecyclerView.Adapter实现如下:
public abstract class RecycleViewAdapter extends RecyclerView.Adapter {
private List iRecycleViewData;
@NonNull
@Override
public RecycleViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
if (viewType <= 0) {
Log.e("RecycleViewAdapter", "Please make your data implement IRecycleViewData");
return null;
}
return new RecycleViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(viewType, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull RecycleViewHolder viewHolder, int position) {
bindData(viewHolder, iRecycleViewData.get(position), position);
}
@Override
public void onBindViewHolder(@NonNull RecycleViewHolder holder, int position, @NonNull List
这里封装了一些基本的操作,可自行扩展。
RecyclerView.ViewHolder
公共ViewHolder的代码实现如下:
public class RecycleViewHolder extends RecyclerView.ViewHolder {
private SparseArray viewSparseArray;
public RecycleViewHolder(@NonNull View itemView) {
super(itemView);
viewSparseArray = new SparseArray<>();
}
public View getView(int id) {
View view = viewSparseArray.get(id);
if (view == null) {
view = itemView.findViewById(id);
viewSparseArray.put(id, view);
}
return view;
}
public RecycleViewHolder setText(int id, String text) {
((TextView) getView(id)).setText(text);
return this;
}
public RecycleViewHolder setTextColor(int id, int textColor) {
((TextView) getView(id)).setTextColor(textColor);
return this;
}
public RecycleViewHolder setTextSize(int id, int textSize) {
((TextView) getView(id)).setTextSize(textSize);
return this;
}
}
这里只给了几个基本的对view操作的方法,可自行完善。
例子
定义三个数据类型:
//左边的对话
public class LeftMessage implements IRecycleViewData {
private String message;
public LeftMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public int getItemViewId() {
return R.layout.view_left_message;
}
}
//右边的对话
public class RightMessage extends LeftMessage {
public RightMessage(String message) {
super(message);
}
@Override
public int getItemViewId() {
return R.layout.view_right_message;
}
}
//时间戳
public class TimeMessage implements IRecycleViewData {
private String time;
public TimeMessage(String time) {
this.time = time;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
@Override
public int getItemViewId() {
return R.layout.view_time_message;
}
}
Adapter的使用
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private RecyclerView recyclerView;
private RecycleViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.add).setOnClickListener(this);
findViewById(R.id.delete).setOnClickListener(this);
recyclerView = findViewById(R.id.recycle_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
initAdapter();
}
@Override
protected void onDestroy() {
super.onDestroy();
recyclerView.setAdapter(null);
if (adapter != null) {
adapter.clear();
adapter = null;
}
}
private void initAdapter() {
adapter = new RecycleViewAdapter() {
@Override
protected void bindData(@NonNull RecycleViewHolder viewHolder, IRecycleViewData data, int position) {
if (data instanceof TimeMessage) {
viewHolder.setText(R.id.time, ((TimeMessage) data).getTime());
} else if (data instanceof LeftMessage) {
viewHolder.setText(R.id.message, ((LeftMessage) data).getMessage());
} else if (data instanceof RightMessage) {
viewHolder.setText(R.id.message, ((RightMessage) data).getMessage());
}
}
};
recyclerView.setAdapter(adapter);
addData();
}
private void addData() {
List data = new ArrayList<>();
data.add(new TimeMessage(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())));
data.add(new LeftMessage("你好呀"));
data.add(new RightMessage("很高兴认识你"));
adapter.addData(data);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.add:
addData();
break;
case R.id.delete:
adapter.removeData(0);
break;
}
}
}