1. 概述
1.1 功能列表
- 类之间的关系简单, 两个类搞定(核心代码才几十行), 使用简单方便
- 同时支持单布局多布局
- 支持链式设置 item
- 支持 item 点击和长按事件
- RecyclerView、ListView 之类的 ViewHolder 都可以直接支持
1.2 使用方式
public class TestActivity extends BaseActivity {
private final List<String> data = new ArrayList<>(100);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity_layout);
for (int i = 0; i < 100; i++) {
data.add("text-" + i);
}
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(getMultipleAdapter());
}
private RecyclerView.Adapter getSimpleAdapter() {
return new SimpleAdapter<>(data, android.R.layout.simple_list_item_1, new SimpleAdapter.OnBindViewListener<String>() {
@Override
public void onBindView(ViewHolder holder, List<String> data, int position) {
holder.setText(android.R.id.text1, data.get(position))
.setTextColor(android.R.id.text1, Color.RED)
.setOnItemClickListener((view) ->
Toast.makeText(TestActivity.this, String.valueOf(position), Toast.LENGTH_SHORT).show()
);
if (position == 0) {
TextView textView = holder.getView(android.R.id.text1);
textView.setText(R.string.app_name, TextView.BufferType.NORMAL);
}
}
});
}
private RecyclerView.Adapter getSingleAdapter() {
return new MultipleAdapter<>(data, new MultipleAdapter.OnBindViewListener<String>() {
@Override
public int getItemViewLayout(int position) {
return android.R.layout.simple_list_item_1;
}
@Override
public void onBindView(ViewHolder holder, List<String> data, int position) {
holder.setText(android.R.id.text1, data.get(position));
}
});
}
private RecyclerView.Adapter getMultipleAdapter() {
return new MultipleAdapter<>(data, new MultipleAdapter.OnBindViewListener<String>() {
@Override
public int getItemViewLayout(int position) {
return position % 2 == 0 ? android.R.layout.simple_list_item_1 : android.R.layout.simple_list_item_2;
}
@Override
public void onBindView(ViewHolder holder, List<String> data, int position) {
if (position % 2 == 0) {
holder.setText(android.R.id.text1, data.get(position));
} else {
holder.setText(android.R.id.text1, data.get(position));
holder.setText(android.R.id.text2, "Android");
}
}
});
}
}
2. 单布局版-SimpleAdapter
public class SimpleAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
private final List<T> data;
private final int layoutRes;
private final OnBindViewListener<T> bindViewListener;
public SimpleAdapter(@NonNull List<T> data, @LayoutRes int layoutRes, @NonNull OnBindViewListener<T> bindViewListener) {
this.data = data;
this.layoutRes = layoutRes;
this.bindViewListener = bindViewListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
return new ViewHolder(inflater.inflate(layoutRes, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
if (bindViewListener != null) {
bindViewListener.onBindView(holder, data, position);
}
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
public interface OnBindViewListener<T> {
void onBindView(ViewHolder holder, List<T> data, int position);
}
}
3. 多布局版-MultipleAdapter
- 让 getItemViewType() 函数返回布局文件, 而不是返回布局类型
- getItemViewType() 返回的布局文件会传递到给 onCreateViewHolder(), 这样我们就可以创建不同的布局文件 ViewHolder 了; 改几行代码就从单布局版变成了多布局版本了
public class MultipleAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
private final List<T> data;
private final OnBindViewListener<T> bindViewListener;
public MultipleAdapter(@NonNull List<T> data, @NonNull OnBindViewListener<T> bindViewListener) {
this.data = data;
this.bindViewListener = bindViewListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int layoutRes) {
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
return new ViewHolder(inflater.inflate(layoutRes, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
if (bindViewListener != null) {
bindViewListener.onBindView(holder, data, position);
}
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public int getItemViewType(int position) {
return bindViewListener == null ? View.NO_ID : bindViewListener.getItemViewLayout(position);
}
public interface OnBindViewListener<T> {
int getItemViewLayout(int position);
void onBindView(ViewHolder holder, List<T> data, int position);
}
}
4. 通用 RecyclerHolder
public class ViewHolder extends RecyclerView.ViewHolder {
private final Context context;
private final SparseArray<View> mSparseArray;
ViewHolder(@NonNull View itemView) {
super(itemView);
mSparseArray = new SparseArray<>();
context = BaseApplication.getApplication();
}
@SuppressWarnings("unchecked")
public final <T extends View> T getView(@IdRes int viewId) {
View view = mSparseArray.get(viewId);
if (view == null) {
view = itemView.findViewById(viewId);
mSparseArray.put(viewId, view);
}
return (T) view;
}
public ViewHolder setVisibility(int viewId, int visibility) {
View view = getView(viewId);
view.setVisibility(visibility);
return this;
}
public ViewHolder setPadding(int viewId, int left, int top, int right, int bottom) {
View view = getView(viewId);
view.setPadding(left, top, right, bottom);
return this;
}
public ViewHolder setSelected(int viewId, boolean selected) {
View view = getView(viewId);
view.setSelected(selected);
return this;
}
public ViewHolder setBackgroundColor(int viewId, @ColorInt int color) {
View view = getView(viewId);
view.setBackgroundColor(color);
return this;
}
public ViewHolder setBackgroundRes(int viewId, @DrawableRes int resId) {
View view = getView(viewId);
view.setBackgroundResource(resId);
return this;
}
public ViewHolder setBackgroundDrawable(int viewId, Drawable drawable) {
View view = getView(viewId);
view.setBackground(drawable);
return this;
}
public ViewHolder setBackgroundBitmap(int viewId, Bitmap bitmap) {
View view = getView(viewId);
view.setBackground(new BitmapDrawable(context.getResources(), bitmap));
return this;
}
public ViewHolder setEnabled(int viewId, boolean enabled) {
View view = getView(viewId);
view.setEnabled(enabled);
return this;
}
public boolean isEnabled(int viewId) {
return getView(viewId).isEnabled();
}
public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
public ViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}
public ViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
public ViewHolder setOnItemClickListener(View.OnClickListener listener) {
itemView.setClickable(true);
itemView.setOnClickListener(listener);
return this;
}
public ViewHolder onItenLongClickListener(View.OnLongClickListener listener) {
itemView.setLongClickable(true);
itemView.setOnLongClickListener(listener);
return this;
}
public ViewHolder setText(int viewId, CharSequence value) {
TextView view = getView(viewId);
view.setText(value);
return this;
}
public ViewHolder setTextSize(int viewId, int testSize) {
TextView view = getView(viewId);
view.setTextSize(testSize);
return this;
}
public ViewHolder setTextColor(int viewId, @ColorInt int textColor) {
TextView view = getView(viewId);
view.setTextColor(textColor);
return this;
}
public ViewHolder setTextColorRes(int viewId, @ColorRes int color) {
TextView view = getView(viewId);
view.setTextColor(context.getResources().getColor(color));
return this;
}
public ViewHolder setTextDrawable(int viewId, Drawable left, Drawable top, Drawable right, Drawable bottom) {
TextView textView = getView(viewId);
textView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
return this;
}
public ViewHolder addTextChangedListener(int viewId, TextWatcher watcher) {
EditText editText = getView(viewId);
editText.addTextChangedListener(watcher);
return this;
}
public ViewHolder setOnCheckedChangeListener(int viewId, final CheckBox.OnCheckedChangeListener listener) {
CheckBox checkBox = getView(viewId);
checkBox.setOnCheckedChangeListener(listener);
return this;
}
public ViewHolder setChecked(int viewId, boolean checked) {
Checkable view = getView(viewId);
view.setChecked(checked);
return this;
}
public boolean isChecked(int viewId) {
CheckBox checkBox = getView(viewId);
return checkBox.isChecked();
}
public ViewHolder setMax(int viewId, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
return this;
}
public ViewHolder setPressed(int viewId, boolean pressed) {
View view = getView(viewId);
view.setPressed(pressed);
return this;
}
public ViewHolder setImageResource(int viewId, int imageResId) {
ImageView view = getView(viewId);
view.setImageResource(imageResId);
return this;
}
public ViewHolder setImageDrawable(int viewId, Drawable drawable) {
ImageView view = getView(viewId);
view.setImageDrawable(drawable);
return this;
}
public ViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
}