SlimAdapter 简单适配器

SlimAdapter 简单适配器创建:

SlimAdapter<String> slimAdapter = SlimAdapter.create(-1, new SlimAdapter.Inject<String>() {

    @Override
    public void onInject(SlimAdapter.ViewInjector viewInjector, String items) throws Exception {
        viewInjector.text(R.id.all, items)
                .text(R.id.basic, items);
    }
});
package com.kun.arno.test.tools;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.SparseArrayCompat;
import android.text.util.Linkify;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.request.RequestOptions;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author Arno
 * @date 2018/7/18 0018
 * @des
 */
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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/nuonuonuonuonuo/article/details/81206733
今日推荐