package com.freelib.multiitem.adapter.holder; import android.databinding.DataBindingUtil; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView.ViewHolder; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.freelib.multiitem.item.ItemData; /** * ViewHolder的管理类 * 需要继承此类,实现ViewHolder的创建{@link #onCreateViewHolder}与绑定{@link #onBindViewHolder} * * @author free46000 */ public abstract class ViewHolderManager<T, V extends BaseViewHolder> { private boolean fullSpan; private int spanSize; protected ViewModel viewModel = new BaseViewModel(); /** * 创建ViewHolder * {@link android.support.v7.widget.RecyclerView.Adapter#onCreateViewHolder} */ @NonNull public abstract V onCreateViewHolder(@NonNull ViewGroup parent); /** * 为ViewHolder绑定数据 * {@link android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder} * * @param t 数据源 */ public abstract void onBindViewHolder(V holder, T t); /** * 为ViewHolder绑定数据,并根据params做出相应设置 * * @param t 数据源 * @param params {@link ViewHolderParams} */ public void onBindViewHolder(@NonNull V holder, @NonNull T t, @NonNull ViewHolderParams params) { // TODO 如果以后有需要不直接在item view上设置Click事件,在MultiViewHolder增加itemHandlerView属性即可 if (isClickable()) { holder.itemView.setOnClickListener(params.getClickListener()); holder.itemView.setOnLongClickListener(params.getLongClickListener()); } //如果数据源是ItemData,则执行定制化处理 if (t instanceof ItemData) { bindView(holder, (ItemData) t); } onBindViewHolder(holder, t); } protected void bindView(V holder, ItemData data) { setVisibility(holder.itemView, data.getVisibility()); } protected void setVisibility(View itemView, int visibility) { itemView.setVisibility(visibility); } public final int getPosition(@NonNull final ViewHolder holder) { return holder.getAdapterPosition(); } /** * 通过资源id生成item itemView * * @param parent onCreateViewHolder中的参数 * @return 返回item itemView */ protected View getItemView(ViewGroup parent) { return viewModel.getItemView(parent, getItemLayoutId()); } /** * item布局文件id * * @return layout资源id */ @LayoutRes protected abstract int getItemLayoutId(); /** * 在指定view中获取控件为id的view * * @param view 外层view * @param id 需要获取view的控件id * @return itemView */ protected <T extends View> T getView(View view, int id) { return (T) view.findViewById(id); } /** * 在指定viewHolder中获取控件为id的view * * @return itemView */ protected <T extends View> T getView(ViewHolder viewHolder, int id) { return getView(viewHolder.itemView, id); } /** * @param fullSpan 是否需要填满父布局(适用于表格布局) */ public void setFullSpan(boolean fullSpan) { this.fullSpan = fullSpan; } /** * @return 是否填满父布局 * @see StaggeredGridLayoutManager.LayoutParams#setFullSpan * @see GridLayoutManager#setSpanSizeLookup */ public boolean isFullSpan() { return fullSpan; } /** * 根据spanCount获取当前所占span大小(适用于表格布局)<br> * 如果被设置过正整数则返回;如果是fullSpan则返回spanCount;其余返回1<br> * GridLayoutManager模式下,调整本方法返回值达到不同Item占用不同宽度的功能 * * @param spanCount span总数量 * @return 当前所占span大小 * @see GridLayoutManager#setSpanSizeLookup */ public int getSpanSize(int spanCount) { return spanSize > 0 ? spanSize : (isFullSpan() ? spanCount : 1); } /** * @param spanSize 所占span大小 */ public void setSpanSize(int spanSize) { this.spanSize = spanSize; } public boolean isClickable() { return true; } /** * 开启Data bind * * @see ViewModel */ protected void enableDataBind() { viewModel = new DataBindViewModel(); } interface ViewModel { View getItemView(ViewGroup parent, @LayoutRes int layoutId); } static class BaseViewModel implements ViewModel { @Override public View getItemView(ViewGroup parent, @LayoutRes int layoutId) { return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); } } static class DataBindViewModel implements ViewModel { @Override public View getItemView(ViewGroup parent, @LayoutRes int layoutId) { return DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), layoutId, parent, false).getRoot(); } } }