DataBinding使用指南(三)ListView、RecycleView通用Adapter
在第一章DataBinding使用指南(一)DataBinding基本使用,雙向綁定,ListView RecycleView使用 中我們發現 ListView和RecycleView 的Adapter中代碼都極其相似並和不同數據無特別大的牽扯。故我們想應該可以使用 DataBinding 寫出一個通用Adapter
ListView 通用Adapter
我們直接上代碼
/**
* 基於 DataBinding 的通用 Adapter
*/
public class CommonListAdapter<T> extends BaseAdapter {
private ObservableList<T> observableList;
private int variableId;
private @LayoutRes int layoutId;
public CommonListAdapter(@NonNull ObservableList<T> observableList, int variableId, @LayoutRes int layoutId) {
this.observableList = observableList;
this.variableId = variableId;
this.layoutId = layoutId;
}
@Override
public int getCount() {
return observableList == null ? 0 : observableList.size();
}
@Override
public T getItem(int position) {
return observableList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Nullable
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewDataBinding binding;
if (convertView == null) {
//這裏的最後一個參數必須爲 false
binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), layoutId, parent, false);
convertView = binding.getRoot();
} else {
binding = DataBindingUtil.getBinding(convertView);
}
binding.setVariable(variableId, getItem(position));
return convertView;
}
}
使用方法和普通Adapter的使用方法相同。注意一下構造函數的參數
observableList
這個自然是數據源;variableId
這個是 變量的id值列表,類似於R。這個參數用在這裏binding.setVariable(variableId, getItem(position));
當你的數據項是User的時候,這個參數就會是BR.user
。layoutId
佈局的ID
RecycleView 通用 Adapter
我還是喜歡直接上代碼,如果你看不懂代碼可以再來問我。
public class CommonRecycleViewAdapter<T> extends RecyclerView.Adapter {
private ObservableList<T> observableList;
private int variableId;
private @LayoutRes int layoutId;
private OnRecycleViewItemClickListener onRecycleViewItemClickListener;
public CommonRecycleViewAdapter(@NonNull ObservableList<T> observableList, int variableId, @LayoutRes int layoutId) {
this.observableList = observableList;
this.variableId = variableId;
this.layoutId = layoutId;
observableList.addOnListChangedCallback(new BaseOnListChangeCallback());
}
@NonNull
@Override
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
//這裏的第四個參數必須爲 false 這在Google
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), layoutId, viewGroup, false);
return new BaseViewHolder(binding.getRoot());
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int i) {
ViewDataBinding binding = DataBindingUtil.getBinding(viewHolder.itemView);
binding.setVariable(variableId, observableList.get(i));
//設置item點擊監聽
binding.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onRecycleViewItemClickListener != null) {
onRecycleViewItemClickListener.itemClick(observableList.get(i), i);
}
}
});
}
@Override
public int getItemCount() {
return observableList != null ? observableList.size() : 0;
}
class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(@NonNull View itemView) {
super(itemView);
}
}
public OnRecycleViewItemClickListener getOnRecycleViewItemClickListener() {
return onRecycleViewItemClickListener;
}
public void setOnRecycleViewItemClickListener(OnRecycleViewItemClickListener onRecycleViewItemClickListener) {
this.onRecycleViewItemClickListener = onRecycleViewItemClickListener;
}
//數據變化監聽
class BaseOnListChangeCallback extends ObservableList.OnListChangedCallback {
@Override
public void onChanged(ObservableList sender) {
}
@Override
public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) {
CommonRecycleViewAdapter.this.notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) {
CommonRecycleViewAdapter.this.notifyItemRangeInserted(positionStart, itemCount);
}
@Override
public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) {
CommonRecycleViewAdapter.this.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) {
CommonRecycleViewAdapter.this.notifyItemRangeRemoved(positionStart, itemCount);
}
}
/**
* RecycleView 的 Item 點擊監聽
* @param <T>
*/
interface OnRecycleViewItemClickListener<T> {
/**
*
* @param item 點擊的 Item 對應的數據
* @param position 點擊的 Item 位置
*/
void itemClick(T item, int position);
}
}
用法和普通的Adapter是一樣的。參數的含義和上面ListView的一樣。
這裏我還貼心的加上了一個 Item 的點擊監聽。你只要在Activity中爲Adapter設置這個監聽就可以了。
來,看代碼
adapter.setOnRecycleViewItemClickListener(new CommonRecycleViewAdapter.OnRecycleViewItemClickListener<User>() {
@Override
public void itemClick(User item, int position) {
System.out.println(item.getName());
}
});
好了,經過上面這些亂七八糟的操作 ListView、RecycleView的通用Adapter就完成了。這樣我們就可以省去很多的重複性代碼。簡直nice啊。