涂鸦礼物初版实现

This commit is contained in:
huangjian
2022-08-18 10:10:59 +08:00
parent d2f6e5c8ff
commit cd79f0ec3a
27 changed files with 1190 additions and 699 deletions

View File

@@ -2,7 +2,9 @@ package com.yizhuan.xchat_android_library.bindinglist;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableList;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
@@ -16,47 +18,31 @@ import java.util.List;
* Created by lvzebiao on 2018/10/23.
*/
public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
public class MultiTypeAdapter<T extends IItem> extends RecyclerView.Adapter<ItemViewHolder> {
private List<IItem> headersItems = new ArrayList<>();
public List<IItem> getHeadersItems() {
return headersItems;
}
private ObservableList<IItem> footersItems = new ObservableArrayList<>();
private final WeakReferenceOnListChangedCallback<T> callback = new WeakReferenceOnListChangedCallback<>(this);
private List<T> headersItems = new ArrayList<>();
private ObservableList<T> footersItems = new ObservableArrayList<>();
/**
* 此数据源表示真正的数据, 保留用于其他逻辑计算
*/
private List<IItem> dataItems;
public List<IItem> getData() {
return dataItems;
}
private List<T> dataItems;
/**
* 此list表示RecyclerView显示的所有item即header+data+footer
*/
private ObservableList<IItem> allItems = new ObservableArrayList<>();
public List<IItem> getAllItems() {
return allItems;
}
private ObservableList<T> allItems = new ObservableArrayList<>();
private boolean canLoadMore = false;
public void setCanLoadMore(boolean canLoadMore) {
this.canLoadMore = canLoadMore;
}
private RecyclerView recyclerView;
private final WeakReferenceOnListChangedCallback callback = new WeakReferenceOnListChangedCallback(this);
private int variableId;
private boolean needItemClick;
private T loadMoreItem;
private List<T> statusList = new ArrayList<>();
private T startLoadingItem;
private T netErrorItem;
private T emptyItem;
private OnItemClickListener<T> listener;
public MultiTypeAdapter(List<IItem> list, int variableId, boolean needItemClick) {
public MultiTypeAdapter(List<T> list, int variableId, boolean needItemClick) {
if (list == null) {
list = new ObservableArrayList<>();
}
@@ -74,6 +60,28 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
this(null, variableId, false);
}
static void ensureChangeOnMainThread() {
if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
throw new IllegalStateException("You must only modify the ObservableList on the main thread.");
}
}
public List<T> getHeadersItems() {
return headersItems;
}
public List<T> getData() {
return dataItems;
}
public List<T> getAllItems() {
return allItems;
}
public void setCanLoadMore(boolean canLoadMore) {
this.canLoadMore = canLoadMore;
}
/**
* 这方法不会清除header清除header调用
* {@link #clearAllItem()}
@@ -87,7 +95,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
if (headersItems.size() == 0) {
allItems.clear();
} else {
// List<IItem> tempList = new ArrayList<>();
// List<T> tempList = new ArrayList<>();
// for (int i = headersItems.size(); i < allItems.size(); i++) {
// tempList.add(allItems.get(i));
// }
@@ -110,7 +118,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
allItems.clear();
}
public void addData(List<IItem> list) {
public void addData(List<T> list) {
dataItems.addAll(list);
int insertPos = allItems.size() - footersItems.size();
if (insertPos < 0) {
@@ -119,14 +127,12 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
allItems.addAll(insertPos, list);
}
public void addHeaderItem(IItem headerItem) {
public void addHeaderItem(T headerItem) {
headersItems.add(headerItem);
allItems.add(0, headerItem);
}
private IItem loadMoreItem;
public void setLoadMoreView(IItem item) {
public void setLoadMoreView(T item) {
if (!canLoadMore || item == null) {
return;
}
@@ -151,14 +157,11 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
}
}
private List<IItem> statusList = new ArrayList<>();
private IItem startLoadingItem;
/**
* 此方法并不是所有list都需要不需要则传null
* 只是客户端有个加载动画,所以添加
*/
public void startLoading(IItem item) {
public void startLoading(T item) {
if (item == null) {
return;
}
@@ -171,12 +174,10 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
}
}
private IItem netErrorItem;
/**
* 如果有数据不添加错误item
*/
public void setNetError(IItem item) {
public void setNetError(T item) {
if (item == null) {
return;
}
@@ -195,9 +196,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
}
}
private IItem emptyItem;
public void setEmpty(IItem item) {
public void setEmpty(T item) {
if (item == null) {
return;
}
@@ -221,24 +220,22 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
public void hideStatus() {
statusList.clear();
if (startLoadingItem != null && allItems.contains(startLoadingItem)) {
if (startLoadingItem != null) {
allItems.remove(startLoadingItem);
}
if (netErrorItem != null && allItems.contains(netErrorItem)) {
if (netErrorItem != null) {
allItems.remove(netErrorItem);
}
if (emptyItem != null && allItems.contains(emptyItem)) {
if (emptyItem != null) {
allItems.remove(emptyItem);
}
}
public void clearLoarMoreView() {
footersItems.clear();
}
@Override
public int getItemViewType(int position) {
return allItems.get(position).getType();
@@ -252,7 +249,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
final IItem item = getIndexItem(position);
final T item = getIndexItem(position);
holder.bindTo(variableId, item);
if (needItemClick) {
holder.binding.getRoot().setOnClickListener(v -> {
@@ -268,7 +265,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
return allItems.size();
}
public IItem getIndexItem(int position) {
public T getIndexItem(int position) {
return allItems.get(position);
}
@@ -280,16 +277,10 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
this.recyclerView = recyclerView;
}
private OnItemClickListener listener;
public void setOnItemClickListener(OnItemClickListener listener) {
public void setOnItemClickListener(OnItemClickListener<T> listener) {
this.listener = listener;
}
public interface OnItemClickListener {
void onClick(IItem item);
}
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
if (this.recyclerView != null && allItems != null) {
@@ -298,16 +289,20 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
this.recyclerView = null;
}
private static class WeakReferenceOnListChangedCallback extends ObservableList.OnListChangedCallback<ObservableList<IItem>> {
final WeakReference<MultiTypeAdapter> adapterRef;
public interface OnItemClickListener<T extends IItem> {
void onClick(T item);
}
WeakReferenceOnListChangedCallback(MultiTypeAdapter adapter) {
private static class WeakReferenceOnListChangedCallback<T extends IItem> extends ObservableList.OnListChangedCallback<ObservableList<T>> {
final WeakReference<MultiTypeAdapter<T>> adapterRef;
WeakReferenceOnListChangedCallback(MultiTypeAdapter<T> adapter) {
this.adapterRef = new WeakReference<>(adapter);
}
@Override
public void onChanged(ObservableList sender) {
MultiTypeAdapter adapter = adapterRef.get();
MultiTypeAdapter<T> adapter = adapterRef.get();
if (adapter == null) {
return;
}
@@ -317,7 +312,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
@Override
public void onItemRangeChanged(ObservableList sender, final int positionStart, final int itemCount) {
MultiTypeAdapter adapter = adapterRef.get();
MultiTypeAdapter<T> adapter = adapterRef.get();
if (adapter == null) {
return;
}
@@ -327,7 +322,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
@Override
public void onItemRangeInserted(ObservableList sender, final int positionStart, final int itemCount) {
MultiTypeAdapter adapter = adapterRef.get();
MultiTypeAdapter<T> adapter = adapterRef.get();
if (adapter == null) {
return;
}
@@ -337,7 +332,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
@Override
public void onItemRangeMoved(ObservableList sender, final int fromPosition, final int toPosition, final int itemCount) {
MultiTypeAdapter adapter = adapterRef.get();
MultiTypeAdapter<T> adapter = adapterRef.get();
if (adapter == null) {
return;
}
@@ -349,7 +344,7 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
@Override
public void onItemRangeRemoved(ObservableList sender, final int positionStart, final int itemCount) {
MultiTypeAdapter adapter = adapterRef.get();
MultiTypeAdapter<T> adapter = adapterRef.get();
if (adapter == null) {
return;
}
@@ -357,10 +352,4 @@ public class MultiTypeAdapter extends RecyclerView.Adapter<ItemViewHolder> {
adapter.notifyItemRangeRemoved(positionStart, itemCount);
}
}
static void ensureChangeOnMainThread() {
if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
throw new IllegalStateException("You must only modify the ObservableList on the main thread.");
}
}
}