封装通用 Adapter 实现上拉加载更多

阅读 5

下拉刷新,上拉加载是 RecyclerView 中最常用的功能。下拉刷新可以使用 SwipeRefreshLayout 等实现,加载更多如何实现呢?

public abstract class MCyclerAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    protected List<T> list;
    protected Context context;
    protected LayoutInflater inflater;
    private final static int FOOT_TYPE = 99;

    /**
     * 设置自己的底部加载更多的布局
     *
     * @param customFootView
     */
    public void setCustomFootView(View customFootView) {
        isLoadMore = true;
        this.customFootView = customFootView;
    }

    private View customFootView;

    public boolean isMultiType() {
        return isMultiType;
    }

    public boolean isLoadMore() {
        return isLoadMore;
    }

    /**
     * 设置是否底部显示加载更多,默认不显示
     *
     * @param isLoadMore
     */
    public void setIsLoadMore(boolean isLoadMore) {
        this.isLoadMore = isLoadMore;
    }

    private boolean isLoadMore = false;

    /**
     * 设置是否是多种布局,默认单一布局
     *
     * @param isMultiType
     */
    public void setIsMultiType(boolean isMultiType) {
        this.isMultiType = isMultiType;
    }

    private boolean isMultiType = false;

    public MCyclerAdapter(List<T> list, Context context) {
        this.list = list;
        this.context = context;
        inflater = LayoutInflater.from(context);
    }

    /**
     * 如果你的item布局是多种,需要复写这个方法
     *
     * @param postion
     * @return
     */
    public abstract int getDisplayType(int postion);

    @Override
    public int getItemViewType(int position) {
        if (isLoadMore && position == getItemCount() - 1) {
            return FOOT_TYPE;
        }
        if (isMultiType) {
            return getDisplayType(position);
        }
        return super.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (isLoadMore && viewType == FOOT_TYPE) {
            View view = null;
            if (customFootView != null) {
                view = customFootView;
            } else {
                view = inflater.inflate(R.layout.bottom_progressbar, parent, false);
            }
            return new FootHolder(view);
        }
        return onCreateDisplayHolder(parent, viewType);
    }


    public abstract RecyclerView.ViewHolder onCreateDisplayHolder(ViewGroup parent, int viewType);

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if (isLoadMore && position == getItemCount() - 1) {

            if (moreListerner != null) {
                handler.sendEmptyMessageDelayed(11, 300);
            }
            return;
        }
        onBindData(holder, position);
    }

    public abstract void onBindData(RecyclerView.ViewHolder holder, int position);

    /**
     * 返回列表长度
     *
     * @return
     */
    @Override
    public int getItemCount() {

        if (isLoadMore)
            return list == null || list.size() == 0 ? 0 : list.size() + 1;
        return list == null || list.size() == 0 ? 0 : list.size();
    }

    class FootHolder extends RecyclerView.ViewHolder {
        public FootHolder(View itemView) {
            super(itemView);
        }
    }

    public OnLoadMoreListerner getMoreListerner() {
        return moreListerner;
    }

    public void setMoreListerner(OnLoadMoreListerner moreListerner) {
        this.moreListerner = moreListerner;
    }

    private OnLoadMoreListerner moreListerner;

    public interface OnLoadMoreListerner {
        public void loadMore();

    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            moreListerner.loadMore();

        }
    };

    /**
     * 如果你需要有item的点击事件,你自己的ViewHolder extends BaseHolder
     */
    class BaseHolder extends RecyclerView.ViewHolder {

        public CycleItemClilkListener getCycleItemClilkListener() {
            return cycleItemClilkListener;
        }

        public void setCycleItemClilkListener(CycleItemClilkListener cycleItemClilkListener) {
            this.cycleItemClilkListener = cycleItemClilkListener;
        }

        private CycleItemClilkListener cycleItemClilkListener;

        public BaseHolder(View itemView, CycleItemClilkListener listener) {
            super(itemView);
            cycleItemClilkListener = listener;
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if (cycleItemClilkListener != null) {
                        cycleItemClilkListener.onCycleItemClick(v, getPosition());
                    }
                }
            });
        }
    }

    public interface CycleItemClilkListener {
        void onCycleItemClick(View view, int position);
    }
}

1. 滚动到末尾位置时加载一个Foot布局,isLoadMore用于标记是否需要加载更多默认不需要,getItemCount返回长度,注意需要加载更多时长度是数据长度+1
 
public int getItemViewType(int position) {
    if (isLoadMore && position == getItemCount() - 1) {
        return FOOT_TYPE;
    }
    if (isMultiType) {
        return getDisplayType(position);
    }
    return super.getItemViewType(position);
}
 
@Override
public int getItemCount() {
    if (isLoadMore) {
        return list == null || list.size() == 0 ? 0 : list.size() + 1;
    }
    return list == null || list.size() == 0 ? 0 : list.size();
}
 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (isLoadMore && position == getItemCount() - 1) {
        if (moreListerner != null) {
            handler.sendEmptyMessageDelayed(11, 300);
        }
        return;
    }
    onBindData(holder, position);
}
 
2. 多种布局与加载更多一个思路,这里我定义了一个抽象方法getDisplayType方便子类去实现
 
if (isMultiType) {
    return getDisplayType(position);
}
 
3. 因为在构造View Holder时,rootView将作为一个必传参数传递进来,所以我们只需要拿到rootView并给其绑定点击监听事件即可。这里我定义了一个带有点击事件的ViewHolder,需要时直接继承BaseViewHolder
 
class BaseHolder extends RecyclerView.ViewHolder {

    public CycleItemClilkListener getCycleItemClilkListener() {
        return cycleItemClilkListener;
    }

    public void setCycleItemClilkListener(CycleItemClilkListener cycleItemClilkListener) {
        this.cycleItemClilkListener = cycleItemClilkListener;
    }

    private CycleItemClilkListener cycleItemClilkListener;

    public BaseHolder(View itemView, CycleItemClilkListener listener) {
        super(itemView);
        cycleItemClilkListener = listener;
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (cycleItemClilkListener != null) {
                    cycleItemClilkListener.onCycleItemClick(v, getPosition());
                }
            }
        });
    }
}

public interface CycleItemClilkListener {
    void onCycleItemClick(View view, int position);
}
 
一切就绪可以试一试效果了,定义一个adapter 继承MCyclerAdapter
 
public class Madapter extends MCyclerAdapter<DisplayData> {
    @Override
    public int getDisplayType(int postion) {
        return list.get(postion).getType();
    }

    public Madapter(List<DisplayData> list, Context context) {
        super(list, context);
    }

    @Override
    public RecyclerView.ViewHolder onCreateDisplayHolder(ViewGroup parent, int viewType) {

        View view = null;
        RecyclerView.ViewHolder holder = null;
        switch (viewType) {
            case DisplayData.TYPE_TXT:
                view = inflater.inflate(R.layout.item_txt, parent, false);
                holder = new TextHolder(view);
                break;
            case DisplayData.TYPE_IMG:
                view = inflater.inflate(R.layout.item_img, parent, false);
                holder = new ImageHolder(view);
                break;
            case DisplayData.TYPE_MULTI:
                break;
        }
        return holder;
    }

    @Override
    public void onBindData(RecyclerView.ViewHolder holder, int position) {

        DisplayData data = list.get(position);
        switch (getDisplayType(position)) {
            case DisplayData.TYPE_TXT:
                TextHolder textHolder = (TextHolder) holder;
                textHolder.mTxt.setText(data.getContent());
                break;
            case DisplayData.TYPE_IMG:
                ImageHolder imageHolder = (ImageHolder) holder;
                if (data.getContent().equals("1")) {
                    imageHolder.mImg.setImageResource(R.drawable.img001);
                } else {
                    imageHolder.mImg.setImageResource(R.drawable.img002);
                }
                break;
            case DisplayData.TYPE_MULTI:
                break;
        }
    }

    class TextHolder extends BaseHolder {

        TextView mTxt;

        public TextHolder(View itemView) {
            super(itemView, new CycleItemClilkListener() {
                @Override
                public void onCycleItemClick(View view, int position) {
                    Toast.makeText(context, position + "", Toast.LENGTH_SHORT).show();
                }
            });
            mTxt = (TextView) itemView.findViewById(R.id.mText);
        }
    }

    class ImageHolder extends RecyclerView.ViewHolder {

        ImageView mImg;

        public ImageHolder(View itemView) {
            super(itemView);
            mImg = (ImageView) itemView.findViewById(R.id.mImg);
        }
    }
}
原文:https://blog.csdn.net/HanFLy_x/article/details/47137763
各位看官,如果你觉得本文不错,请支持一下~