万能适配器Adapter

SlimAdapter 简单适配器创建试例:

       SlimAdapter.<VehicleIncidentsDetails>create(R.layout.list_layout_event_point, (view, info) -> {
            //车牌号码
            view.text(R.id.occurrence_car_number, info.getCarNo())
                    //车辆别名
                    .text(R.id.occurrence_carAlias, info.getCarAlias())
                    //事件类型值
                    .text(R.id.electronic_status, info.getEventTypeVal())
                    //发生时间
                    .text(R.id.occurrence_time, info.getBeginTime())
                    //持续时长
                    .text(R.id.occurrence_duration, info.getContinueTimeStr())
                    //路线名称
                    .text(R.id.route_name, info.getRouteName())
                    //发生区域
                    .text(R.id.occurrence_area, info.getOverspeedZone())
                    //发生地点
                    .text(R.id.occurrence_address, info.getAddress())
                    //最高速度
                    .text(R.id.occurrence_max_speed, info.getMaxSpeed())
                    //开始地点
                    .text(R.id.starting_place, info.getAddress())
                    //结束地点
                    .text(R.id.finish_place, info.getEndAddress())
                    //显示隐藏
                    .visible(R.id.route_name_ll, info.isLineOffset())
                    .visible(R.id.occurrence_area_ll, info.isRegionalSpeeding())
                    .visible(R.id.occurrence_max_speed_ll, info.isRegionalSpeeding())
                    .visible(R.id.occurrence_address_ll, !info.isFatigueDriving())
                    .visible(R.id.starting_place_ll, info.isFatigueDriving())
                    .visible(R.id.finish_place_ll, info.isFatigueDriving());
        });
public final class SlimAdapter<T> extends BaseAdapter {

    public interface Inject<T> {
        /**
         * 业务处理
         *
         * @param viewInjector
         * @param items
         * @throws Exception 捕获业务处理异常
         */
        void onInject(ViewInjector viewInjector, T items) throws Exception;
    }


    private List<T> mList = null;
    private final Object mLock = new Object();
    private boolean mNotifyOnChange = true;
    private int layoutResId = -1;
    private Inject<T> inject = null;

    private SlimAdapter() {
    }

    /**
     * 获取adpter的实例
     *
     * @param layoutResId
     * @param inject
     * @param <T>
     * @return
     */
    public static <T> SlimAdapter<T> create(int layoutResId, SlimAdapter.Inject<T> inject) {
        return SlimAdapter.create(layoutResId, inject, new ArrayList<T>());
    }

    /**
     * 获取adpter的实例
     *
     * @param layoutResId
     * @param inject
     * @param mList
     * @param <T>
     * @return
     */
    public static <T> SlimAdapter<T> create(int layoutResId, SlimAdapter.Inject<T> inject, T... mList) {
        return SlimAdapter.create(layoutResId, inject, Arrays.asList(mList));
    }

    /**
     * 获取adpter的实例
     *
     * @param layoutResId
     * @param inject
     * @param mList
     * @param <T>
     * @return
     */
    public static <T> SlimAdapter<T> create(int layoutResId, SlimAdapter.Inject<T> inject, List<T> mList) {
        return new SlimAdapter<T>().registerInject(layoutResId, inject, mList);
    }

    /**
     * 注册信息
     *
     * @param layoutResId
     * @param inject
     * @param mList
     * @return
     */
    private SlimAdapter registerInject(int layoutResId, Inject<T> inject, List<T> mList) {
        this.inject = inject;
        this.layoutResId = layoutResId;
        this.mList = mList;
        return this;
    }

    /**
     * 获取item 视图
     *
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return obtainViewInjector(position, convertView, parent).getView(inject, getItem(position));
    }

    /**
     * 获取item view
     *
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    private ViewInjector obtainViewInjector(int position, View convertView, ViewGroup parent) {
        return convertView != null ? (ViewInjector) convertView.getTag() : obtainItemViewInjector(position, parent);
    }

    /**
     * 构建ViewInjector
     *
     * @param position
     * @param parent
     * @return
     */
    private ViewInjector obtainItemViewInjector(int position, ViewGroup parent) {
        return new ViewInjector(obtainItemView(position, parent));
    }

    /**
     * 可重载加载自定义视图
     *
     * @param position
     * @param parent
     * @return
     */
    protected View obtainItemView(int position, ViewGroup parent) {
        try {
            return LayoutInflater.from(parent.getContext()).inflate(obtainItemViewLayoutId(position), parent, false);
        } catch (Exception e) {
            throw layoutResId < 0 ? new SlimAdapterException("layoutResId is cannot be empty") : new SlimAdapterException(e);
        }
    }

    /**
     * 可重载加载自定义布局
     *
     * @param position
     * @return
     */
    protected int obtainItemViewLayoutId(int position) {
        return layoutResId;
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    @Override
    public boolean areAllItemsEnabled() {//areAllItemsEnabled 返回true,也就是默认没有分隔符,所有item都可点击可选择;
        return super.areAllItemsEnabled();
    }


    /**
     * 注册适配器
     *
     * @param absListView
     * @return
     */
    private SlimAdapter attachTo(AbsListView absListView) {
        absListView.setAdapter(this);
        return this;
    }

    /**
     * 注册适配器
     *
     * @param view
     * @return
     */
    public SlimAdapter attachTo(View view) {
        try {
            return attachTo((AbsListView) view);
        } catch (Exception e) {
            throw new SlimAdapterException(view == null ? "attachToView is cannot be empty" : view.getClass().getSimpleName() + " is cannot be converted to AbsListView");
        }
    }


    public void add(T item) {
        synchronized (mLock) {
            mList.add(item);
        }
        notifyDataSetChanged();
    }

    public void addAll(Collection<? extends T> collection) {
        if (collection != null) {
            synchronized (mLock) {
                mList.addAll(collection);
            }
            notifyDataSetChanged();
        }
    }

    public void addAllToHeard(Collection<? extends T> collection) {
        synchronized (mLock) {

            mList.addAll(0, collection);
        }
        notifyDataSetChanged();
    }

    public void addAll(T... items) {
        synchronized (mLock) {
            Collections.addAll(mList, items);
        }
        notifyDataSetChanged();
    }

    public void insert(T item, int index) {
        synchronized (mLock) {
            mList.add(index, item);
        }
        notifyDataSetChanged();
    }

    public void remove(T item) {
        synchronized (mLock) {
            mList.remove(item);
        }
        notifyDataSetChanged();
    }

    public void clear() {
        synchronized (mLock) {
            mList.clear();
        }
        notifyDataSetChanged();
    }

    public void sort(Comparator<? super T> comparator) {
        synchronized (mLock) {
            Collections.sort(mList, comparator);
        }
        notifyDataSetChanged();
    }

    @Override
    public void notifyDataSetChanged() {
        if (mNotifyOnChange) {
            super.notifyDataSetChanged();
        }
    }

    @Override
    public int getCount() {
        try {
            return mList.size();
        } catch (Exception e) {
            return 0;
        }
    }

    @Nullable
    @Override
    public T getItem(int position) {
        try {
            return mList.get(position);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * @author
     * @date
     * @des
     */
    public static class ViewInjector {

        /**
         * Views indexed with their IDs
         */
        private final SparseArrayCompat<View> views;


        private View convertView;


        protected ViewInjector(ViewGroup parent, int layoutId) {
            this(LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false));
        }

        protected ViewInjector(View convertView) {
            this.views = new SparseArrayCompat<>();
            this.convertView = convertView;
            this.convertView.setTag(this);
        }

        /**
         * This method is package private and should only be used by QuickAdapter.
         */
        public static ViewInjector get(View convertView, ViewGroup parent, @LayoutRes int layoutId) {
            if (convertView == null) {
                return new ViewInjector(parent, layoutId);
            }
            // Retrieve the existing helper and update its position
            ViewInjector existingHelper = (ViewInjector) convertView.getTag();
            return existingHelper;
        }

        /**
         * This method allows you to retrieve a view and perform custom
         * operations on it, not covered by the BaseAdapterHelper.<br/>
         * If you think it's a common use case, please consider creating
         * a new issue at https://github.com/JoanZapata/base-adapter-helper/issues.
         *
         * @param viewId The id of the view you want to retrieve.
         */
        public <T extends View> T getView(int viewId) {
            return retrieveView(viewId);
        }

        /**
         * Will set the text of a TextView.
         *
         * @param viewId The view id.
         * @param value  The text to put in the text view.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector text(int viewId, String value) {
            TextView view = retrieveView(viewId);
            view.setText(value);
            return this;
        }

        /**
         * Will set the image of an ImageView from a resource id.
         *
         * @param viewId     The view id.
         * @param imageResId The image resource id.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector image(int viewId, int imageResId) {
            ImageView view = retrieveView(viewId);
            view.setImageResource(imageResId);
            return this;
        }

        /**
         * Will set background color of a view.
         *
         * @param viewId The view id.
         * @param color  A color, not a resource id.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setBackgroundColor(int viewId, int color) {
            View view = retrieveView(viewId);
            view.setBackgroundColor(color);
            return this;
        }

        /**
         * Will set background of a view.
         *
         * @param viewId        The view id.
         * @param backgroundRes A resource to use as a background.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setBackgroundRes(int viewId, int backgroundRes) {
            View view = retrieveView(viewId);
            view.setBackgroundResource(backgroundRes);
            return this;
        }

        /**
         * Will set text color of a TextView.
         *
         * @param viewId    The view id.
         * @param textColor The text color (not a resource id).
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector textcolor(int viewId, @ColorInt int textColor) {
            TextView view = retrieveView(viewId);
            view.setTextColor(textColor);
            return this;
        }

        /**
         * Will set text color of a TextView.
         *
         * @param viewId       The view id.
         * @param textColorRes The text color resource id.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector textcolorResId(int viewId, @ColorRes int textColorRes) {
            TextView view = retrieveView(viewId);
            view.setTextColor(ContextCompat.getColor(getContext(), textColorRes));
            return this;
        }

        public ViewInjector setGlideImageLoad(int viewId, String load) {
            Glide.with(getContext()).load(load).into((ImageView) retrieveView(viewId));
            return this;
        }

        public ViewInjector setGlideImageLoad(int viewId, String load, @DrawableRes int drawaleRes) {
            Glide.with(getContext()).load(load).apply(new RequestOptions().error(drawaleRes)).into((ImageView) retrieveView(viewId));
            return this;
        }

        /**
         * Will set the image of an ImageView from a drawable.
         *
         * @param viewId   The view id.
         * @param drawable The image drawable.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector drawable(int viewId, Drawable drawable) {
            ImageView view = retrieveView(viewId);
            view.setImageDrawable(drawable);
            return this;
        }

        /**
         * Will download an image from a URL and put it in an ImageView.<br/>
         * It uses Square's Picasso library to download the image asynchronously and put the result into the ImageView.<br/>
         * Picasso manages recycling of views in a ListView.<br/>
         * If you need more control over the Picasso settings, use {BaseAdapterHelper#setImageBuilder}.
         *
         * @param viewId   The view id.
         * @param imageUrl The image URL.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setImageUrl(int viewId, String imageUrl) {
            ImageView view = retrieveView(viewId);
            Glide.with(getContext()).load(imageUrl).into(view);
            return this;
        }

        /**
         * @param viewId
         * @param imageUrl
         * @param error
         * @return
         */
        public ViewInjector setImageUrl(int viewId, String imageUrl, int error) {
            ImageView view = retrieveView(viewId);
            Glide.with(getContext()).load(imageUrl).apply(new RequestOptions().error(error)).into(view);
            return this;
        }

        /**
         * @param viewId
         * @param imageUrl
         * @param placeholder
         * @param error
         * @return
         */
        public ViewInjector setImageUrl(int viewId, String imageUrl, int placeholder, int error) {
            ImageView view = retrieveView(viewId);
            Glide.with(getContext()).load(imageUrl).apply(new RequestOptions().placeholder(placeholder).error(error)).into(view);
            return this;
        }

        /**
         * Will download an image from a URL and put it in an ImageView.<br/>
         *
         * @param viewId The view id.
         * @param load   The Picasso request builder. (e.g. Picasso.with(context).load(imageUrl))
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setImageBuilder(int viewId, RequestBuilder<Drawable> load) {
            ImageView view = retrieveView(viewId);
            load.into(view);
            return this;
        }

        /**
         * Add an action to set the image of an image view. Can be called multiple times.
         */
        public ViewInjector bitmap(int viewId, Bitmap bitmap) {
            ImageView view = retrieveView(viewId);
            view.setImageBitmap(bitmap);
            return this;
        }

        /**
         * Add an action to set the alpha of a view. Can be called multiple times.
         * Alpha between 0-1.
         */
        public ViewInjector alpha(int viewId, float value) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                retrieveView(viewId).setAlpha(value);
            } else {
                // Pre-honeycomb hack to set Alpha value
                AlphaAnimation alpha = new AlphaAnimation(value, value);
                alpha.setDuration(0);
                alpha.setFillAfter(true);
                retrieveView(viewId).startAnimation(alpha);
            }
            return this;
        }

        /**
         * Set a view visibility to VISIBLE (true) or GONE (false).
         *
         * @param viewId  The view id.
         * @param visible True for VISIBLE, false for GONE.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector visible(int viewId, boolean visible) {
            View view = retrieveView(viewId);
            view.setVisibility(visible ? View.VISIBLE : View.GONE);
            return this;
        }

        /**
         * Add links into a TextView.
         *
         * @param viewId The id of the TextView to linkify.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector linkify(int viewId) {
            TextView view = retrieveView(viewId);
            Linkify.addLinks(view, Linkify.ALL);
            return this;
        }

        /**
         * Apply the typeface to the given viewId, and enable subpixel rendering.
         */
        public ViewInjector setTypeface(int viewId, Typeface typeface) {
            TextView view = retrieveView(viewId);
            view.setTypeface(typeface);
            view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
            return this;
        }

        /**
         * Apply the typeface to all the given viewIds, and enable subpixel rendering.
         */
        public ViewInjector setTypeface(Typeface typeface, int... viewIds) {
            for (int viewId : viewIds) {
                TextView view = retrieveView(viewId);
                view.setTypeface(typeface);
                view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
            }
            return this;
        }

        /**
         * Sets the progress of a ProgressBar.
         *
         * @param viewId   The view id.
         * @param progress The progress.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector progress(int viewId, int progress) {
            ProgressBar view = retrieveView(viewId);
            view.setProgress(progress);
            return this;
        }

        /**
         * Sets the progress and max of a ProgressBar.
         *
         * @param viewId   The view id.
         * @param progress The progress.
         * @param max      The max value of a ProgressBar.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector progress(int viewId, int progress, int max) {
            ProgressBar view = retrieveView(viewId);
            view.setMax(max);
            view.setProgress(progress);
            return this;
        }

        /**
         * Sets the range of a ProgressBar to 0...max.
         *
         * @param viewId The view id.
         * @param max    The max value of a ProgressBar.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector max(int viewId, int max) {
            ProgressBar view = retrieveView(viewId);
            view.setMax(max);
            return this;
        }

        /**
         * Sets the rating (the number of stars filled) of a RatingBar.
         *
         * @param viewId The view id.
         * @param rating The rating.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector rating(int viewId, float rating) {
            RatingBar view = retrieveView(viewId);
            view.setRating(rating);
            return this;
        }

        /**
         * Sets the rating (the number of stars filled) and max of a RatingBar.
         *
         * @param viewId The view id.
         * @param rating The rating.
         * @param max    The range of the RatingBar to 0...max.
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector rating(int viewId, float rating, int max) {
            RatingBar view = retrieveView(viewId);
            view.setMax(max);
            view.setRating(rating);
            return this;
        }

        /**
         * Sets the on click listener of the view.
         *
         * @param viewId   The view id.
         * @param listener The on click listener;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector clicked(int viewId, View.OnClickListener listener) {
            View view = retrieveView(viewId);
            view.setOnClickListener(listener);
            return this;
        }

        /**
         * Sets the on touch listener of the view.
         *
         * @param viewId   The view id.
         * @param listener The on touch listener;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setOnTouchListener(int viewId, View.OnTouchListener listener) {
            View view = retrieveView(viewId);
            view.setOnTouchListener(listener);
            return this;
        }

        /**
         * Sets the on long click listener of the view.
         *
         * @param viewId   The view id.
         * @param listener The on long click listener;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
            View view = retrieveView(viewId);
            view.setOnLongClickListener(listener);
            return this;
        }

        /**
         * Sets the listview or gridview's item_image click listener of the view
         *
         * @param viewId   The view id.
         * @param listener The item_image on click listener;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener) {
            AdapterView view = retrieveView(viewId);
            view.setOnItemClickListener(listener);
            return this;
        }

        /**
         * Sets the listview or gridview's item_image long click listener of the view
         *
         * @param viewId   The view id.
         * @param listener The item_image long click listener;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener) {
            AdapterView view = retrieveView(viewId);
            view.setOnItemLongClickListener(listener);
            return this;
        }

        /**
         * Sets the listview or gridview's item_image selected click listener of the view
         *
         * @param viewId   The view id.
         * @param listener The item_image selected click listener;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector setOnItemSelectedClickListener(int viewId, AdapterView.OnItemSelectedListener listener) {
            AdapterView view = retrieveView(viewId);
            view.setOnItemSelectedListener(listener);
            return this;
        }

        /**
         * Sets the tag of the view.
         *
         * @param viewId The view id.
         * @param tag    The tag;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector tag(int viewId, Object tag) {
            View view = retrieveView(viewId);
            view.setTag(tag);
            return this;
        }

        /**
         * Sets the tag of the view.
         *
         * @param viewId The view id.
         * @param key    The key of tag;
         * @param tag    The tag;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector tag(int viewId, int key, Object tag) {
            View view = retrieveView(viewId);
            view.setTag(key, tag);
            return this;
        }

        /**
         * Sets the checked status of a checkable.
         *
         * @param viewId  The view id.
         * @param checked The checked status;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector checked(int viewId, boolean checked) {
            Checkable view = (Checkable) retrieveView(viewId);
            view.setChecked(checked);
            return this;
        }

        /**
         * Sets the adapter of a adapter view.
         *
         * @param viewId  The view id.
         * @param adapter The adapter;
         * @return The BaseAdapterHelper for chaining.
         */
        public ViewInjector adapter(int viewId, Adapter adapter) {
            AdapterView view = retrieveView(viewId);
            view.setAdapter(adapter);
            return this;
        }

        /**
         * 获取item视图
         */
        public <R> View getView(Inject<R> inject, R items) {
            this.onInject(inject, items);
            return convertView;
        }

        /**
         * 执行业务操作
         *
         * @param inject
         * @param items
         * @param <R>
         */
        public <R> void onInject(Inject<R> inject, R items) {
            try {
                if (inject != null) {
                    inject.onInject(this, items);
                }
            } catch (Exception e) {
                Log.i("=====>", "SlimAdapter.Inject.onInject====>" + e);
                throw new SlimAdapterException(e);
            }
        }

        @SuppressWarnings("unchecked")
        protected <T extends View> T retrieveView(int viewId) {
            View view = views.get(viewId);
            if (view == null) {
                view = convertView.findViewById(viewId);
                views.put(viewId, view);
            }
            return (T) view;
        }


        private Context getContext() {
            try {
                return convertView.getContext();
            } catch (Exception e) {
                throw new SlimAdapterException("Gilde context is cannot be empty");
            }
        }
    }

    public static class SlimAdapterException extends RuntimeException {

        public SlimAdapterException(Throwable cause) {
            super(cause);
        }

        public SlimAdapterException(String message) {
            super(message);
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值