RecyclerView的万能适配器+定义可以到底部自动刷新的RecyclerView

RecyclerView的重要性就不做重复说明了,为了方便以后直接使用写了这个,主要有:

  万能适配器在使用的时候分为定义布局和绑定数据,方便直接套用。加入了底部刷新,需要配合自己写的RecyclerView一起使用,对于布局中各个子布局和控件可以做到响应各种点击事件:

    首先抽取ViewHolder:这里的要点是用到了SparseArray(源码中类似ArrayList。直接使用Object数组进行实现):

    

package com.fightzhao.baseadapterdemo.base;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by fightzhao on 16/5/10.
 */
public class BaseRecyclerViewHolder extends RecyclerView.ViewHolder {
    //集合类,layout里包含的View,以view的id作为key,value是view对象()
    protected SparseArray<View> mViews;
    protected Context mContext;

    public BaseRecyclerViewHolder(Context context, View itemView) {
        super(itemView);
        mContext = context;
        mViews = new SparseArray<View>();
    }

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

    public View getView(int viewId) {
        return findViewById(viewId);
    }

    public TextView getTextView(int viewId) {
        return (TextView) getView(viewId);
    }

    public Button getButton(int viewId) {
        return (Button) getView(viewId);
    }

    public ImageView getImageView(int viewId) {
        return (ImageView) getView(viewId);
    }

    public ImageButton getImageButton(int viewId) {
        return (ImageButton) getView(viewId);
    }

    public EditText getEditText(int viewId) {
        return (EditText) getView(viewId);
    }

    /**
     * 实现底部转圈圈的效果,这里可以定制的,比如使用吃豆人的效果
     * @param viewId
     * @return
     */
    public AnimationDrawable getAnimationDrawable(int viewId) {
        return (AnimationDrawable) getView(viewId).getBackground();
    }

    public BaseRecyclerViewHolder setText(int viewId, String value) {
        TextView view = findViewById(viewId);
        view.setText(value);
        return this;
    }

    public BaseRecyclerViewHolder setBackground(int viewId, int resId) {
        View view = findViewById(viewId);
        view.setBackgroundResource(resId);
        return this;
    }

    public BaseRecyclerViewHolder setClickListener(int viewId, View.OnClickListener listener) {
        View view = findViewById(viewId);
        view.setOnClickListener(listener);
        return this;
    }

}

  

 

BaseAdapter代码:

package com.fightzhao.baseadapterdemo.base;

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.fightzhao.baseadapterdemo.R;
import com.fightzhao.baseadapterdemo.callback.OnItemClickListener;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by fightzhao on 16/5/10.
 * RecyclerView通用适配器
 */
public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<BaseRecyclerViewHolder> {
    /**
     * RecyclerView的加载样式
     * 当滑动到底部时候的加载
     */
    public static final int TYPE_HEADER = 1;
    public static final int TYPE_ITEM = 2;
    public static final int TYPE_FOOTER = 3;

    protected List<T> mData;
    protected Context mContext;
    protected LayoutInflater mInflater;
    protected OnItemClickListener mClickListener;
    private RecyclerView.LayoutManager mLayoutManager;

    protected boolean mUseAnimation;
    protected boolean mShowFooter;

    private int mLastPosition = -1;

    /**
     * 瀑布流
     *
     * @param savedInstanceState
     */
    private List<Integer> mHeights;

    public BaseRecyclerAdapter(Context context, List<T> data) {
        this(context, data, true);
    }

    public BaseRecyclerAdapter(Context context, List<T> data, boolean useAnimation) {
        this(context, data, useAnimation, null);
    }

    public BaseRecyclerAdapter(Context context, List<T> data, boolean useAnimation, RecyclerView.LayoutManager layoutManager) {
        mContext = context;
        mUseAnimation = useAnimation;
        mLayoutManager = layoutManager;
        mData = data == null ? new ArrayList<T>() : data;
        mInflater = LayoutInflater.from(context);

        mHeights = new ArrayList<Integer>();
        for (int i = 0; i < mData.size(); i++) {
            mHeights.add((int) (100 + Math.random() * 300));
        }

    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mClickListener = listener;
    }

    @Override
    public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_FOOTER) {
            // 底部加载更多的样式
            return new BaseRecyclerViewHolder(mContext, mInflater.inflate(R.layout.item_load_more, parent, false));
        } else {
            // 正常情况下的布局样式和点击事件(以接口的形式向外提供)
            final BaseRecyclerViewHolder holder = new BaseRecyclerViewHolder(mContext,
                    mInflater.inflate(getItemLayoutId(viewType), parent, false));
            if (mClickListener != null) {

                /**
                 * 点击事件
                 */
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mClickListener.onItemClick(v, holder.getLayoutPosition());
                    }
                });

                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        mClickListener.onItemLongClick(v, holder.getLayoutPosition());
                        return false;
                    }
                });

                holder.getTextView(R.id.tv_title).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mClickListener.onTextViewClick(v, holder.getLayoutPosition());
                    }
                });
            }
            return holder;
        }
    }

    @Override
    public void onBindViewHolder(BaseRecyclerViewHolder holder, int position) {
        if (getItemViewType(position) == TYPE_FOOTER) {
            if (mLayoutManager != null) {
                if (mLayoutManager instanceof StaggeredGridLayoutManager) {
                    if (((StaggeredGridLayoutManager) mLayoutManager).getSpanCount() != 1) {
                        StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) holder.itemView
                                .getLayoutParams();
                        params.setFullSpan(true);

                    } else if (mLayoutManager instanceof GridLayoutManager) {
                        if (((GridLayoutManager) mLayoutManager)
                                .getSpanCount() != 1 && ((GridLayoutManager) mLayoutManager)
                                .getSpanSizeLookup() instanceof GridLayoutManager.DefaultSpanSizeLookup) {
                            throw new RuntimeException("网格布局列数大于1时应该继承SpanSizeLookup时处理底部加载时布局占满一行。");
                        }
                    }
                }
            }

            // 底部加载的处理
            holder.getImageView(R.id.loading_icon).setVisibility(View.VISIBLE);
            holder.getAnimationDrawable(R.id.loading_icon).start();
        } else {
            // 布局样式处理完毕后,处理数据
            bindData(holder, position, mData.get(position));
            if (mUseAnimation) {
                setAnimation(holder.itemView, position);
            }

        }


    }

    @Override
    public int getItemCount() {
        int i = mShowFooter ? 1 : 0;
        return mData != null ? mData.size() + i : 0;
    }

    /**
     * Item的样式布局Id
     *
     * @param viewType
     * @return
     */
    public abstract int getItemLayoutId(int viewType);

    @Override
    public int getItemViewType(int position) {
        if (mShowFooter && getItemCount() - 1 == position) {
            return TYPE_FOOTER;
        }
        return bindViewType(position);
    }

    protected int bindViewType(int position) {
        return 0;
    }

    /**
     * 绑定数据
     *
     * @param holder
     * @param position
     * @param item
     */
    public abstract void bindData(BaseRecyclerViewHolder holder, int position, T item);

    /**
     * 动画的处理
     *
     * @param viewToAnimate
     * @param position
     */
    protected void setAnimation(View viewToAnimate, int position) {
        if (position > mLastPosition) {
            Animation animation = AnimationUtils
                    .loadAnimation(viewToAnimate.getContext(), R.anim.item_bottom_in);
            viewToAnimate.startAnimation(animation);
            mLastPosition = position;
        }
    }

    /**
     * Adapter显示尾部
     */
    public void showFooter() {
        notifyItemInserted(getItemCount());
        mShowFooter = true;
    }

    /**
     * Adapter隐藏尾部
     */
    public void hideFooter() {
        notifyItemRemoved(getItemCount() - 1);
        mShowFooter = false;
    }

    public void setData(List<T> data) {
        mData = data;
        notifyDataSetChanged();
    }

    public void add(int pos, T item) {
        mData.add(pos, item);
        notifyItemInserted(pos);
    }

    public void delete(int pos) {
        mData.remove(pos);
        notifyItemRemoved(pos);
    }

    public void addMoreData(List<T> data) {
        int startPos = mData.size();
        mData.addAll(data);
        notifyItemRangeInserted(startPos, data.size());
    }

    public List<T> getData() {
        return mData;
    }
}

  

    

posted @ 2016-05-12 21:25  fightzhao  阅读(937)  评论(0编辑  收藏  举报