首先写一个数据变化观察的工厂: ListFactory
public class ListFactory {
public static ObservableList.OnListChangedCallback getListChangedCallback(RecyclerView.Adapter adapter) {
return new ObservableList.OnListChangedCallback() {
@Override
public void onChanged(ObservableList sender) {
adapter.notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) {
adapter.notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) {
adapter.notifyItemRangeInserted(positionStart, itemCount);
adapter.notifyItemRangeChanged(positionStart,adapter.getItemCount()-positionStart);
}
@Override
public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) {
if (itemCount == 1) {
adapter.notifyItemMoved(fromPosition, toPosition);
} else {
adapter.notifyDataSetChanged();
}
}
@Override
public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) {
adapter.notifyItemRemoved(positionStart);
adapter.notifyItemRangeChanged(positionStart,adapter.getItemCount()-positionStart);
}
};
}
}
然后是BindingViewHolder:
public class BindingViewHolder<T extends ViewDataBinding> extends RecyclerView.ViewHolder {
public T mBinding;
public BindingViewHolder(@NonNull T binding) {
super(binding.getRoot());
mBinding = binding;
}
public T getBinding() {
return mBinding;
}
}
下面是 ObservableArrayList_BaseRecyclerViewAdapter:,没有详细写foot_view功能,有空加上
public abstract class ObservableArrayList_BaseRecyclerViewAdapter<T, VDB extends ViewDataBinding> extends RecyclerView.Adapter<BindingViewHolder<VDB>> {
private LayoutInflater layoutInflater;
private OnItemClickListener mListener; //item的点击监听器
protected ObservableArrayList<T> data_list;
private int NORMAL_TYPE = 0; // 第一种ViewType,正常的item
private int FOOT_TYPE = 1; // 第二种ViewType,底部的提示View
public ObservableArrayList<T> getList() {
return data_list;
}
public void delete(int position) {
data_list.remove(position);
// notifyItemRangeRemoved(position,1);
}
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
return FOOT_TYPE;
} else {
return NORMAL_TYPE;
}
}
public void reset(int position, T data) {
data_list.set(position, data);
}
public void add(int position, T data) {
data_list.add(position, data);
}
public void setData_list(ObservableArrayList<T> data_list) {
this.data_list = data_list;
}
public interface OnItemClickListener {
public void onItemClickListener(Object data, int position);
}
public ObservableArrayList_BaseRecyclerViewAdapter(Context context) {
this.layoutInflater = LayoutInflater.from(context);
this.data_list = new ObservableArrayList<>();
}
protected abstract int getRecyclerViewItemID();
protected abstract void onBindVH(BindingViewHolder holder, int position);
@NonNull
@Override
public BindingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == NORMAL_TYPE) {
ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, getRecyclerViewItemID(), parent, false);
return new BindingViewHolder(binding);
} else if (viewType == FOOT_TYPE) {
ViewDataBinding footbinding = DataBindingUtil.inflate(layoutInflater, R.layout.rv_footer, parent, false);
return new BindingViewHolder<>(footbinding);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull BindingViewHolder holder, int position) {
if (position < data_list.size()) {
T data = data_list.get(position);
onBindVH(holder, position);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.onItemClickListener(data, holder.getAdapterPosition());
}
}
});
} else {
TextView textView = holder.itemView.findViewById(R.id.test5_tv_footer);
if (TextUtils.isEmpty(textView.getText()))
textView.setText("加载进行中");
}
}
@Override
public int getItemCount() {
return data_list != null ? data_list.size() + 1 : 0;
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
}
public void addAll(ObservableArrayList<T> datas) {
// data_list.clear();
data_list.addAll(datas);
//notifyDataSetChanged();
}
}
下面是正式引用例子: 实例化 base_adapter
MyRecyclerView_Adapter: 实体就是String ,这个有空我优化一下,就是
public class MyRecyclerView_Adapter<T> extends ObservableArrayList_BaseRecyclerViewAdapter<String, Test5Fragment2RvItemBinding> {
ObservableArrayList<T> observableArrayList;
public MyRecyclerView_Adapter(Context context, ObservableArrayList<T> observableArrayList) {
super(context);
this.observableArrayList = observableArrayList;
}
@Override
protected int getRecyclerViewItemID() {
return R.layout.test5_fragment2_rv_item;
}
@Override
protected void onBindVH(BindingViewHolder holder, int position) {
Test5Fragment2RvItemBinding binding = (Test5Fragment2RvItemBinding) holder.getBinding();
binding.test5Fragment5AddBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// observableArrayList.add(position, observableArrayList.get(position));
Loge.e(position + "-----");
add(position, String.valueOf(position) + "位置");
}
});
binding.test5Fragment5DeleteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Loge.e(position + "-----");
delete(position);
}
});
binding.test5Fragment5ResetBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Loge.e(position + "-----");
reset(position, position + ":被修改了" + new Random().nextInt(1000));
}
});
String s = data_list.get(position);
holder.getBinding().setVariable(BR.sssss, s);
holder.getBinding().executePendingBindings();
}
}
fragment 使用: Fragment2_ViewModel
public class Fragment2_ViewModel extends BaseViewModel {
public final ObservableArrayList<String> observableArrayList = new ObservableArrayList<>();
public Fragment2_ViewModel(@NonNull Application application) {
super(application);
}
}
Test5_Fragment2 :
public class Test5_Fragment2 extends BaseFragment<Test5Fragment2Binding> {
@Override
protected int getLayoutId() {
return R.layout.test5_fragment2;
}
@Override
protected void initView() {
// MyRecyclerView_Adapter myRecyclerView_adapter = new MyRecyclerView_Adapter(getContext());
// myRecyclerView_adapter.getList().add("A");
// myRecyclerView_adapter.getList().add("B");
// myRecyclerView_adapter.getList().add("C");
Fragment2_ViewModel fragment2_viewModel = new ViewModelProvider(getActivity()).get(Fragment2_ViewModel.class);
binding.setModel(fragment2_viewModel);
MyRecyclerView_Adapter myRecyclerView_adapter = new MyRecyclerView_Adapter(getContext(), fragment2_viewModel.observableArrayList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
binding.test5Fragment2Rv.setLayoutManager(linearLayoutManager);
binding.setAdaper(myRecyclerView_adapter);
myRecyclerView_adapter.setData_list(fragment2_viewModel.observableArrayList);
fragment2_viewModel.observableArrayList.addOnListChangedCallback(ListFactory.getListChangedCallback(myRecyclerView_adapter));
binding.test5Fragment2Tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = String.valueOf(new Random().nextInt(Integer.MAX_VALUE));
Loge.e(s);
fragment2_viewModel.observableArrayList.add(s);
}
});
binding.test5Fragment2Add5Btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ObservableArrayList<String> stringObservableArrayList = new ObservableArrayList<>();
for (int i = 0; i < 3; i++) {
String s = String.valueOf(new Random().nextInt(Integer.MAX_VALUE));
Loge.e(s);
stringObservableArrayList.add(s);
}
myRecyclerView_adapter.addAll(stringObservableArrayList);
}
});
myRecyclerView_adapter.setOnItemClickListener(new ObservableArrayList_BaseRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClickListener(Object data, int position) {
}
});
}
}
调试效果图:
追加一个局部刷新 的实例:
public class Fragment3_Adapter extends ObservableArrayList_BaseRecyclerViewAdapter<Goods, Test5Fragment3RvItemBinding> {
public Fragment3_Adapter(Context context) {
super(context);
}
@Override
protected int getRecyclerViewItemID() {
return R.layout.test5_fragment3_rv_item;
}
@Override
protected void onBindVH(BindingViewHolder holder, int position) {
Goods goods = data_list.get(position);
Loge.e(goods.toString());
Test5Fragment3RvItemBinding test5Fragment3RvItemBinding = (Test5Fragment3RvItemBinding) holder.getBinding();
holder.getBinding().setVariable(BR.goods, goods);
test5Fragment3RvItemBinding.test5Fragment3DianzanTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Loge.e(String.valueOf(goods.dz));
if (!goods.dz) {
goods.setDianzan("被点赞了");
notifyItemChanged(position, "dianzan");//单项局部刷新,一般用在单项 带图片上,payload 起名一般 用前面bean字段名
// reset(position, goods); 单项刷新,单项不带图片的话,可以偷懒直接用这个。
// notifyDataSetChanged(); 懒人直接用这个,单容易挨 上面叼,用户体验极差
goods.dz = true;
} else {
goods.setDianzan("取消了点赞");
notifyItemChanged(position, "dianzan");
// reset(position, goods);
goods.dz = false;
}
}
});
test5Fragment3RvItemBinding.test5Fragment3DescribeTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
notifyItemChanged(position, "describe");
}
});
}
@Override
public void onBindViewHolder(@NonNull BindingViewHolder<Test5Fragment3RvItemBinding> holder, int position, @NonNull List<Object> payloads) {
if (payloads.isEmpty()) {
onBindViewHolder(holder, position);
} else {
if (((String) payloads.get(0)).trim().equals("dianzan")) {
holder.getBinding().test5Fragment3DianzanTv.setText(data_list.get(position).getDianzan());
} else if (((String) payloads.get(0)).trim().equals("describe")) {
Loge.e(((String) payloads.get(0)).trim());
}
}
}
}
再追加一个 使用differ 的实例:
public class RV_Adapter extends ObservableArrayList_BaseRecyclerViewAdapter<Teacher, DifferRvItemBinding> {
public RV_Adapter(Context context) {
super(context);
}
@Override
protected int getRecyclerViewItemID() {
return R.layout.differ_rv_item;
}
@Override
protected void onBindVH(BindingViewHolder holder, int position) {
Teacher teacher = data_list.get(position);
holder.getBinding().setVariable(BR.teach, teacher);
}
/**
* 常用于刷新,因为 MyDifferCallback 需要传入 具体泛型,写在 base_adapter不方便,就放在子类了
*/
public void differ_addAll(ObservableArrayList<Teacher> observableArrayList) {
ObservableArrayList<Teacher> new_observableArrayList = new ObservableArrayList<>();
new_observableArrayList.addAll(observableArrayList);
Observable.create(new ObservableOnSubscribe<DiffUtil.DiffResult>() {
@Override
public void subscribe(@NonNull ObservableEmitter<DiffUtil.DiffResult> emitter) throws Throwable {
DiffUtil.DiffResult result = DiffUtil.calculateDiff(new MyDifferCallback(data_list, new_observableArrayList), true);
emitter.onNext(result);
emitter.onComplete();
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<DiffUtil.DiffResult>() {
@Override
public void accept(DiffUtil.DiffResult diffResult) throws Throwable {
diffResult.dispatchUpdatesTo(RV_Adapter.this);
setData_list(new_observableArrayList);
}
});
}
// public void differ_add(int position, Teacher teacher) {
// ObservableArrayList<Teacher> new_observableArrayList = new ObservableArrayList<>();
// new_observableArrayList.addAll(getList());
// new_observableArrayList.add(position, teacher);
// getDiffResult(new_observableArrayList);
// }
//
// public void differ_delete(int position) {
// ObservableArrayList<Teacher> new_observableArrayList = new ObservableArrayList<>();
// new_observableArrayList.addAll(getList());
// new_observableArrayList.remove(position);
// getDiffResult(new_observableArrayList);
// }
//
// public void differ_reset(int position, Teacher teacher) {
// ObservableArrayList<Teacher> new_observableArrayList = new ObservableArrayList<>();
// new_observableArrayList.addAll(getList());
// new_observableArrayList.set(position, teacher);
// getDiffResult(new_observableArrayList);
// }
}