软件设计模式中,很多时候组合是优于继承的,组合模式相对来说更加解耦,也更方便维护 recycleview里面的多类型就可以用组合来实现 更方便的修改、维护
一个小demo 说一下思路,实现多类型的同时也是个通用的adapter
class BaseViewHolder : RecyclerView.ViewHolder {
private val views = SparseArray<View>()//保存view
constructor(view: View, convert: LightAdapter.Convert) : super(view) {
this.convert = convert
}
fun getView(@IdRes viewId: Int): View? {
var view: View? = views.get(viewId)
if (view == null) {
view = itemView.findViewById(viewId)
views.put(viewId, view)
}
return view
}
fun setText(viewId: Int, text: String): BaseViewHolder {
var mTextView = getView(viewId) as TextView
mTextView.text = text
return this
}
var convert: LightAdapter.Convert;
}
public class LightAdapter extends RecyclerView.Adapter<BaseViewHolder> {
private @NonNull
List<?> items;
private List<Class> mTypes = new ArrayList<>(); //数据类型
private List<Integer> mLayouts = new ArrayList<>(); //布局类型
private List<Convert> mConverts = new ArrayList<>(); //布局对应的绑定
public LightAdapter register(@LayoutRes int layout, Class mClass, Convert mConvert) {
mTypes.add(mClass);
mLayouts.add(layout);
mConverts.add(mConvert);
return this;
}
public LightAdapter() {
this(Collections.emptyList());
}
public LightAdapter(List<?> items) {
this.items = items;
}
@Override
public int getItemViewType(int position) {
return mTypes.indexOf(items.get(position).getClass()); //判断类型
}
@NonNull
@Override
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(mLayouts.get(viewType), parent, false);
return new BaseViewHolder(itemView, mConverts.get(viewType));
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
holder.convert.convert(holder, position);
}
@Override
public int getItemCount() {
return items.size();
}
public interface Convert {
void convert(BaseViewHolder mBaseViewHolder, int position);
}
}
写的很简单,就2个类 加起来估计150行代码 实现了多类型/单类型的可拔插链式调用,通用的adapter
代码特别特别简单
使用方式就更简单了:
class MainActivity : BaseActivity() {
private lateinit var mLightAdapter: LightAdapter
private var list = mutableListOf<Any>()
override fun getToolbar(): Toolbar? {
return null
}
override fun initView(mSavedInstanceState: Bundle?) {
list.add(Testone("ttttt"))
list.add(TestTwo("2342423424"))
list.add(TestThree("two"))
list.add(Testone("fsdfsf"))
list.add(TestTwo("twy567686o"))
list.add(TestThree("two"))
list.add(Testone("hjkfgh"))
list.add(TestTwo("867867"))
list.add(TestThree("two"))
list.add(Testone("个"))
list.add(TestTwo("645465464"))
list.add(TestThree("two"))
list.add(Testone("过分"))
list.add(TestTwo("78674567gh"))
list.add(TestThree("two"))
mLightAdapter = LightAdapter(list)
.register(R.layout.one, Testone::class.java, LightAdapter.Convert { mBaseViewHolder, position ->
// todo something
})
.register(R.layout.two, TestTwo::class.java, object : LightAdapter.Convert {
override fun convert(mBaseViewHolder: BaseViewHolder?, position: Int) {
// todo something
(mBaseViewHolder?.getView(R.id.yyy) as TextView).text = list.get(position).toString()
}
})
.register(R.layout.three, TestThree::class.java, LightAdapter.Convert { mBaseViewHolder, position ->
// todo something
})
recyclerview.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerview.adapter = mLightAdapter
}
override fun getContentViewLayoutID(): Int {
return R.layout.activity_main2
}
override fun getLoadingTargetView(): View? {
return null
}
}
完成~当你想去掉某个类型直接删掉那个注册类型就行 再也不用小心翼翼的在adapter里面判断类型,各种删除修改东西。。。同时也少了写了很多类 提一下经常用到的 header footer,加载更多,其实都是多类型的实现 ,这里只需要注册一个type 就是一个header/footer,