70行代码写的组合链式调用的通用多类型视图RecycleViewAdapter

本文介绍了一种简化版的通用Adapter——FishAdapter,该Adapter通过插拔式设计支持多种类型的数据展示,简化了RecyclerView中Adapter的编写和维护工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Adapter一定写烦了吧?多种type更是繁琐,修改起来也麻烦,得去Adapter里面各种删东西,逻辑一复杂删个东西都得小心翼翼。。。。。。于是,闲的无聊。写了个简化版的通用可拔插的Adapter,轻喷。。

public class FishAdapter extends RecyclerView.Adapter<Injector.ViewsHolder> {

    private  @NonNull List<?> items;
    private List<Class> mClasses = new ArrayList<>();
    private List<Injector> mInjectors = new ArrayList<>();

    public FishAdapter() {
        this(Collections.emptyList());
    }

    public FishAdapter(@NonNull List<?> items) {
        this.items = items;
    }

    public void setItems(@NonNull List<?> items) {
        this.items = items;
    }

    public static FishAdapter create() {
        return new FishAdapter();
    }

    public <T> FishAdapter register(Class mClass, Injector mInjector) {

        if (mClasses.contains(mClass))
            return this;
        else {
            mClasses.add(mClass);
            mInjectors.add(mInjector);
        }
        return this;
    }

    @Override
    public Injector.ViewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return (Injector.ViewsHolder) mInjectors.get(viewType).instance(parent);
    }

    @Override
    public void onBindViewHolder(Injector.ViewsHolder holder, int position) {
        int type = holder.getItemViewType();
        mInjectors.get(type).onBind(holder, items.get(position));
    }

    @Override
    public int getItemViewType(int position) {
        Object item = items.get(position);
        return mClasses.indexOf(item.getClass());
    }

    @Override
    public int getItemCount() {
        return items == null ? 0 : items.size();
    }

    public FishAdapter attachTo(RecyclerView mRecyclerView) {
        mRecyclerView.setAdapter(this);
        return this;
    }

}
复制代码

乱取的名字,当时在听周深的大鱼海棠 ,就取了个fishAdapter。。。 应该很容易看懂。 此Adapter的做法是:Adapter相当于只是一个存放 Viewholder、分发Viewholder的地方。不管你多少type ,只要注册进来就行。 好,接下来看绑定视图,一看就知道了,使用原来很熟悉的绑定view的方式。

public abstract class Injector<T> {

    public int res;

    public Injector(@NonNull @LayoutRes int res) {
        this.res = res;
    }

    public RecyclerView.ViewHolder getViewHolder(ViewGroup mViewGroup) {
        View root = LayoutInflater.from(mViewGroup.getContext()).inflate(res, mViewGroup, false);

        return new ViewsHolder(root);
    }

    public abstract void onBind(ViewsHolder mViewsHolder, T mT);


    public static class ViewsHolder extends RecyclerView.ViewHolder {

        private SparseArray<View> mViews =new SparseArray<>();

        public ViewsHolder(View itemView) {
            super(itemView);
        }

        //下面是一系列set方法。。。
        public ViewsHolder setText(@IdRes int viewId, CharSequence value) {
            TextView view = getView(viewId);
            view.setText(value);
            return this;
        }

        public ViewsHolder setText(@IdRes int viewId, @StringRes int strId) {
            TextView view = getView(viewId);
            view.setText(strId);
            return this;
        }


        public ViewsHolder setAlpha(@IdRes int viewId, float value) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                getView(viewId).setAlpha(value);
            } else {
                // Pre-honeycomb hack to set Alpha value
                AlphaAnimation alpha = new AlphaAnimation(value, value);
                alpha.setDuration(0);
                alpha.setFillAfter(true);
                getView(viewId).startAnimation(alpha);
            }
            return this;
        }

        public ViewsHolder setVisible(@IdRes int viewId, boolean visible) {
            View view = getView(viewId);
            view.setVisibility(visible ? View.VISIBLE : View.GONE);
            return this;
        }

        public ViewsHolder linkify(@IdRes int viewId) {
            TextView view = getView(viewId);
            Linkify.addLinks(view, Linkify.ALL);
            return this;
        }

        public ViewsHolder setTypeface(@IdRes int viewId, Typeface typeface) {
            TextView view = getView(viewId);
            view.setTypeface(typeface);
            view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
            return this;
        }

        public ViewsHolder setTypeface(Typeface typeface, int... viewIds) {
            for (int viewId : viewIds) {
                TextView view = getView(viewId);
                view.setTypeface(typeface);
                view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
            }
            return this;
        }

        public ViewsHolder setProgress(@IdRes int viewId, int progress) {
            ProgressBar view = getView(viewId);
            view.setProgress(progress);
            return this;
        }

        public ViewsHolder setRating(@IdRes int viewId, float rating) {
            RatingBar view = getView(viewId);
            view.setRating(rating);
            return this;
        }

        public ViewsHolder setOnCheckedChangeListener(@IdRes int viewId, CompoundButton.OnCheckedChangeListener listener) {
            CompoundButton view = getView(viewId);
            view.setOnCheckedChangeListener(listener);
            return this;
        }

        public ViewsHolder setTag(@IdRes int viewId, Object tag) {
            View view = getView(viewId);
            view.setTag(tag);
            return this;
        }

        public ViewsHolder setTag(@IdRes int viewId, int key, Object tag) {
            View view = getView(viewId);
            view.setTag(key, tag);
            return this;
        }

        public ViewsHolder setChecked(@IdRes int viewId, boolean checked) {
            View view = getView(viewId);
            if (view instanceof Checkable) {
                ((Checkable) view).setChecked(checked);
            }
            return this;
        }

        public <T extends View> T getView(@IdRes int viewId) {
            View view = mViews.get(viewId);
            if (view == null) {
                view = itemView.findViewById(viewId);
                mViews.put(viewId, view);
            }
            return (T) view;
        }

    }

}
复制代码

这个就更容易看懂了,绑定view。

好了,我们来看下使用方法。

   mRecyclerView = (RecyclerView) findViewById(R.id.recycleview);
        LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLinearLayoutManager);
        mFishAdapter = FishAdapter.create().register(String.class, new Injector<String>(R.layout.layoutone) {
            @Override
            public void onBind(ViewsHolder mViewsHolder, String mO) {

                mViewsHolder.setText(R.id.text, mO);

            }
        }).register(Test.class, new Injector<Test>(R.layout.layouttwo) {
                    @Override
                    public void onBind(ViewsHolder mViewsHolder, Test mO) {

                        mViewsHolder.setText(R.id.text, mO.name);
                        mViewsHolder.setText(R.id.text2,mO.name+"LOL");

                    }
                })
                .attachTo(mRecyclerView);

        for (int i = 0; i < 10; i++) {

            items.add("爱情公寓" + i);
        }

        for (int i = 0; i < 10; i++) {

            items.add(new Test("爱情公寓视图" + i));
        }

        mFishAdapter.setItems(items);
        mFishAdapter.notifyDataSetChanged();
复制代码

很简单吧。采用链式调用的写法,当你不需要某种type的时候,直接删除或者注释掉就好,也完全不会影响原来的代码。

总结一下:代码一路写过来,慢慢意识到我们在写代码的时候, 组合有可能很多时候打大于继承,拔插式的设计更容易代码的修改维护。demo就不贴了。就上面2个类就没了。 此Adapter 只是随手写的简化版,有很多地方可以完善,github也有十分完善的第三方库,比如:github.com/drakeet/Mul…。谢谢阅读。

转载于:https://juejin.im/post/5a76a33f5188257a836c0868

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值