安卓开发之recyclerview的BaseAdapter的简单封装(一)

github地址 在这里只做一个简单的介绍 , 如果想了解详细代码, 可以去下载源码进行分析

整体的逻辑 为

1.头布局

2加载中的view

3.加载失败的view

4.预加载的界面

5.预加载失败 无数据的情况

6.判断是否到recyclerview的底部

7.是否满一屏  头布局和脚布局时候需要占满一行

首先写一个baseAdapter  继承 recyclerview的adapter 

重写 getItemCount 方法

 @Override
    public int getItemCount() {

        int count;
//获取空布局的数量
        if (getEmptyViewCount() == 1) {
            count = 1;
//正常头布局的数量
            if (getNormalHeaderLayoutCount() != 0) {
                count++;
            }
//正常脚布局的数量
            if (getNormalFooterLayoutCount() != 0) {
                count++;
            }

        } else {
//计算出头布局和脚布局  及正常布局的 总数量
            count = getNormalHeaderLayoutCount() + mDatas.size() + getNormalFooterLayoutCount() + getLoadMoreFooterViewCount();
        }
        return count;
    }

判断布局类型

 @Override
    public int getItemViewType(int position) {
        if (getEmptyViewCount() == 1) {
            if (mEmptyLayout != null && !isRemoveEmptyView && getNormalHeaderLayoutCount() == 0 && getNormalFooterLayoutCount() == 0) {
                return TYPE_EMPTY_VIEW;
            }

            if (isRemoveEmptyView && mReloadView != null) {
                return TYPE_RELOAD_VIEW;
            }

            boolean header = getNormalHeaderLayoutCount() != 0;
            switch (position) {
                case 0:
                    if (header) {
                        return TYPE_NORMAL_HEADER_VIEW;
                    } else {
                        return TYPE_EMPTY_VIEW;
                    }
                case 1:
                    if (header) {
                        return TYPE_EMPTY_VIEW;
                    } else {
                        return TYPE_NORMAL_FOOTER_VIEW;
                    }
                case 2:
                    return TYPE_NORMAL_FOOTER_VIEW;
                default:
                    return TYPE_EMPTY_VIEW;
            }

        }
        if (isNormalHeaderView(position) && getNormalHeaderLayoutCount() != 0) {
            return TYPE_NORMAL_HEADER_VIEW;
        }
        if (isNormalFooterView(position) && getNormalFooterLayoutCount() != 0) {
            return TYPE_NORMAL_FOOTER_VIEW;
        }
        if (isLoadMoreFooterView(position) && getLoadMoreFooterLayoutCount() != 0) {
            return TYPE_FOOTER_VIEW;
        }


        return TYPE_COMMON_VIEW;
    }

Base View Holder 的封装

public class YcBaseViewHolder extends RecyclerView.ViewHolder {
    private SparseArray<View> mViews;
    private View mConvertView;

    public YcBaseViewHolder(View itemView) {
        super(itemView);
        mConvertView = itemView;
        mViews = new SparseArray<>();
    }

    /**
     * 创建 viewHolder
     *
     * @param context
     * @param layoutId
     * @param parent
     * @return
     */
    public static YcBaseViewHolder create(Context context, int layoutId, ViewGroup parent) {
        View itemView = LayoutInflater.from(context).inflate(layoutId, parent, false);
        return new YcBaseViewHolder(itemView);
    }

    public static YcBaseViewHolder create(View itemView) {
        return new YcBaseViewHolder(itemView);
    }

    /**
     * 通过id获得控件
     *
     * @param viewId
     * @param <T>
     * @return
     */
    public <T extends View> T getView(int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = mConvertView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }


    public View getConvertView() {
        return mConvertView;
    }

    public View getSwipeView() {
        ViewGroup itemLayout = ((ViewGroup) mConvertView);
        if (itemLayout.getChildCount() == 2) {
            return itemLayout.getChildAt(1);
        }
        return null;
    }

    //设置条目按钮的监听
    public void setOnClickClickListener(int viewId, View.OnClickListener clickListener) {
        View view = getView(viewId);
        view.setOnClickListener(clickListener);
    }

    public void setText(int viewId, String text) {
        TextView textView = getView(viewId);
        textView.setText(text);
    }

    public void setText(int viewId, int textId) {
        TextView textView = getView(viewId);
        textView.setText(textId);
    }

    public void setTextColor(int viewId, int colorId) {
        TextView textView = getView(viewId);
        textView.setTextColor(colorId);
    }

    public void setBgResource(int viewId, int resId) {
        View view = getView(viewId);
        view.setBackgroundResource(resId);
    }

    public void setBgColor(int viewId, int colorId) {
        View view = getView(viewId);
        view.setBackgroundColor(colorId);
    }

    public void setVisibility(int viewId, int visibility) {
        View view = getView(viewId);
        view.setVisibility(visibility);
    }
}

在BaseAdapter 中 创建holder  根据不同的类型返回 不同的布局

   @Override
    public YcBaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mContext == null) {
            mContext = parent.getContext();
        }
        YcBaseViewHolder viewHolder = null;
        switch (viewType) {
            case TYPE_NORMAL_HEADER_VIEW:
                if (mNormalHeaderLayout == null && mContext != null) {
                    mNormalHeaderLayout = new LinearLayout(mContext);
                }
                viewHolder = YcBaseViewHolder.create(mNormalHeaderLayout);
                break;

            case TYPE_NORMAL_FOOTER_VIEW:
                if (mNormalFooterLayout == null && mContext != null) {
                    mNormalFooterLayout = new LinearLayout(mContext);
                }
                viewHolder = YcBaseViewHolder.create(mNormalFooterLayout);
                break;
            case TYPE_FOOTER_VIEW:
                if (mLoadMoreFooterLayout == null && mContext != null) {
                    mLoadMoreFooterLayout = new RelativeLayout(mContext);
                }
                viewHolder = YcBaseViewHolder.create(mLoadMoreFooterLayout);
                break;
            case TYPE_EMPTY_VIEW:

                if (mEmptyLayout == null && mContext != null) {
                    mEmptyLayout = new FrameLayout(mContext);
                }
                viewHolder = YcBaseViewHolder.create(mEmptyLayout);
                break;

            case TYPE_RELOAD_VIEW:
                viewHolder = YcBaseViewHolder.create(mReloadView);
                break;
        }

        return viewHolder;


    }
 //判断是那种类型的条目 ,空布局,脚布局 , 无数据布局,加载的脚布局,父类的头布局
    protected boolean isCommonItemView(int viewType) {
        return viewType != TYPE_EMPTY_VIEW && viewType != TYPE_FOOTER_VIEW
                && viewType != TYPE_NODATA_VIEW && viewType != TYPE_RELOAD_VIEW
                && viewType != TYPE_NORMAL_HEADER_VIEW && viewType != TYPE_NORMAL_FOOTER_VIEW;
    }

添加和移除脚布局的方法

 /**
     * 添加新的footer view
     *
     * @param footerView
     */
    private void addLoadMoreFooterView(View footerView) {

        if (mLoadMoreFooterLayout == null && mContext != null) {
            mLoadMoreFooterLayout = new RelativeLayout(mContext);
        }

        if (!mLoadMoreEnable || footerView == null) {
            return;
        }

        removeLoadMoreFooterView();
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        mLoadMoreFooterLayout.addView(footerView, params);
    }

    /**
     * 清空footer view
     */
    private void removeLoadMoreFooterView() {
        if (mLoadMoreFooterLayout != null) {
            mLoadMoreFooterLayout.removeAllViews();
        }
    }

空布局 , 加载中 等相关布局的初始化

 /**
     * 初始化加载中布局
     *
     * @param loadingView
     */
    public void setLoadingView(View loadingView) {
        mLoadingView = loadingView;
        addLoadMoreFooterView(mLoadingView);
    }

    public void setLoadingView(int loadingId) {
        if (mContext == null)
            return;
        setLoadingView(UiUtils.inflate(mContext, loadingId));
    }

    /**
     * 初始加载失败布局
     *
     * @param loadFailedView
     */
    public void setLoadFailedView(View loadFailedView) {
        mLoadFailedView = loadFailedView;
    }

    public void setLoadFailedView(int loadFailedId) {
        if (mContext == null)
            return;

        setLoadFailedView(UiUtils.inflate(mContext, loadFailedId));
    }

    /**
     * 初始化全部加载完成布局
     *
     * @param loadEndView
     */
    public void setLoadEndView(View loadEndView) {
        mLoadEndView = loadEndView;
    }

    public void setLoadEndView(int loadEndId) {
        if (mContext == null)
            return;
        setLoadEndView(UiUtils.inflate(mContext, loadEndId));
    }

    public void setEmptyView() {
        if (mContext == null) {
            throw new RuntimeException("YcBaseAdapter -- please Create Adapter first!");
        }
        setEmptyView(UiUtils.inflate(mContext, R.layout.empty_layout));
    }

    public void setEmptyView(int layoutEmptyId) {
        if (mContext == null)
            return;
        setEmptyView(UiUtils.inflate(mContext, layoutEmptyId));
    }

    /**
     * 初始化emptyView
     *
     * @param emptyView
     */
    public void setEmptyView(View emptyView) {
        setEmptyView(emptyView, RecyclerView.LayoutParams.MATCH_PARENT);
    }

    /**
     * 初始化emptyView
     *
     * @param emptyView
     */
    public void setEmptyView(View emptyView, int height) {
        setEmptyView(emptyView, RecyclerView.LayoutParams.MATCH_PARENT, height);
    }


    /**
     * 初始化emptyView
     *
     * @param emptyView
     */
    public void setEmptyView(View emptyView, int width, int height) {
        boolean insert = false;
        if (mEmptyLayout == null) {
            mEmptyLayout = new FrameLayout(emptyView.getContext());
            final RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(width, height);
            final ViewGroup.LayoutParams lp = emptyView.getLayoutParams();
            if (lp != null) {
                layoutParams.width = lp.width;
                layoutParams.height = lp.height;
            }
            mEmptyLayout.setLayoutParams(layoutParams);
            insert = true;
        }
        mEmptyLayout.removeAllViews();
        mEmptyLayout.addView(emptyView);
        if (insert) {
            if (getEmptyViewCount() == 1) {
                int position = 0;
                if (getNormalHeaderLayoutCount() != 0) {
                    position++;
                }
                notifyItemInserted(position);
            }
        }
    }

    /**
     * When the current adapter is empty, the BaseQuickAdapter can display a special view
     * called the empty view. The empty view is used to provide feedback to the user
     * that no data is available in this AdapterView.
     *
     * @return The view to show if the adapter is empty.
     */
    public View getEmptyView() {
        return mEmptyLayout;
    }

    /**
     * 移除emptyView
     */
    public void removeEmptyView() {
        isRemoveEmptyView = true;
        notifyDataSetChanged();
        if (mEmptyLayout != null)
            mEmptyLayout.removeAllViews();
    }

    /**
     * 初次预加载失败、或无数据可显示该view,进行重新加载或提示用户无数据
     *
     * @param reloadView
     */
    public void setReloadView(View reloadView) {
        mReloadView = reloadView;
        removeEmptyView();
    }

    public void setReloadView(int reloadId) {
        if (mContext == null)
            return;
        setReloadView(UiUtils.inflate(mContext, reloadId));
    }

判断HeaderView、FooterView是否占据一行

 

 /**
     * StaggeredGridLayoutManager模式时,HeaderView、FooterView可占据一行
     * <p>
     * Called when a view created by this adapter has been attached to a window.
     * simple to solve item will layout using all
     * {@link #setFullSpan(RecyclerView.ViewHolder)}
     *
     * @param holder
     */
    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        int type = holder.getItemViewType();
        if (!isCommonItemView(type)) {
            setFullSpan(holder);
        }
        //        int position = holder.getLayoutPosition();
        //        if (isLoadMoreFooterView(position) || isHeaderView(position)) {
        //            //设置RecyclerView 的 setFullSpan 为全屏
        //            setFullSpan(holder);
        //        }
    }

    /**
     * When set to true, the item will layout using all span area. That means, if orientation
     * is vertical, the view will have full width; if orientation is horizontal, the view will
     * have full height.
     * if the hold view use StaggeredGridLayoutManager they should using all span area
     *
     * @param holder True if this item should traverse all spans.
     */
    protected void setFullSpan(RecyclerView.ViewHolder holder) {
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) lp;
            params.setFullSpan(true);
        }
    }

    /**
     * GridLayoutManager模式时, HeaderView、FooterView可占据一行,判断RecyclerView是否到达底部
     *
     * @param recyclerView
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        //获取布局管理器
        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) layoutManager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    if (!isCommonItemView(type)) {
                        return gridManager.getSpanCount();
                    }
                    //                     if (isLoadMoreFooterView(position) || isHeaderView(position)) {
                    //                        return gridManager.getSpanCount();
                    //                    }

                    return 1;
                }
            });
        }
        startLoadMore(recyclerView, layoutManager);
    }
判断列表是否滑动到底部
/**
     * 判断列表是否滑动到底部
     *
     * @param recyclerView
     * @param layoutManager
     */
    private void startLoadMore(RecyclerView recyclerView, final RecyclerView.LayoutManager layoutManager) {

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //The RecyclerView is not currently scrolling.
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    //获取加载更多条目的位置 需要加上加载的脚布局
                    int footerViewCount = getLoadMoreFooterViewCount();
                    int lastVisibleItemPosition = findLastVisibleItemPosition(layoutManager) + footerViewCount;
                    int itemCount = getItemCount();
                    Log.d("onScrolled", footerViewCount + " = " + lastVisibleItemPosition + " = " + itemCount);
                    if (lastVisibleItemPosition == itemCount) {
                        Log.d("onScrolled", "执行加载前");
                        if (mLoadMoreEnable && mLoadMoreFooterLayout.getChildAt(0) == mLoadingView && !isLoading) {
                            Log.d("onScrolled", "加载数据");
                            if (mLoadMoreListener != null) {
                                isLoading = true;
                                mLoadMoreListener.onLoadMore(false);
                            }
                        } else if (goneLoadingMore && !isGoneLoadMoreIng) {
                            isGoneLoadMoreIng = true;
                            mHandler.postDelayed(mMyThread, 500);
                        }
                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);


            }
        });
    }
找到最后可见项目位置
 /**
     * 找到最后可见项目位置
     *
     * @param layoutManager
     * @return
     */
    private int findLastVisibleItemPosition(RecyclerView.LayoutManager layoutManager) {
        if (layoutManager instanceof LinearLayoutManager) {
            return ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            final StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
            final int[] positions = new int[staggeredGridLayoutManager.getSpanCount()];
            //            int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(null);
            int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(positions);
            return UiUtils.findMax(lastVisibleItemPositions);
        }
        return -1;
    }
检查是否满一屏的
 /**
     * check if full page after {@link #setNewData(List)}, if full, it will enable load more again.
     * <p>
     * 不是配置项!!
     * <p>
     * 这个方法是用来检查是否满一屏的,所以只推荐在 {@link #setNewData(List)} 之后使用
     * 原理很简单,先关闭 load more,检查完了再决定是否开启
     * <p>
     * 不是配置项!!
     *
     * @param recyclerView your recyclerView
     * @see #setNewData(List)
     */
    public void disableLoadMoreIfNotFullPage(RecyclerView recyclerView) {
        setEnableLoadMore(false);
        if (recyclerView == null)
            return;
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager == null)
            return;
        if (manager instanceof LinearLayoutManager) {
            final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) manager;
            recyclerView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if ((linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1) != getItemCount()) {
                        setEnableLoadMore(true);
                    }
                }
            }, 50);
        } else if (manager instanceof StaggeredGridLayoutManager) {
            final StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) manager;
            recyclerView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    final int[] positions = new int[staggeredGridLayoutManager.getSpanCount()];
                    staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(positions);
                    int pos = getTheBiggestNumber(positions) + 1;
                    if (pos != getItemCount()) {
                        setEnableLoadMore(true);
                    }
                }
            }, 50);
        }
    }


    private int getTheBiggestNumber(int[] numbers) {
        int tmp = -1;
        if (numbers == null || numbers.length == 0) {
            return tmp;
        }
        for (int num : numbers) {
            if (num > tmp) {
                tmp = num;
            }
        }
        return tmp;
    }

 

主要代码就是这些  , 剩下的就是一些 添加数据 , 加载更多脚布局的显示隐藏 ,等等相关代码  直接上代码了  

/**
     * Return root layout of header
     */

    public LinearLayout getHeaderLayout() {
        return mNormalHeaderLayout;
    }

    /**
     * Return root layout of footer
     */
    public LinearLayout getFooterLayout() {
        return mNormalFooterLayout;
    }

    /**
     * Append header to the rear of the mHeaderLayout.
     *
     * @param header
     */
    public int addHeaderView(View header) {
        return addHeaderView(header, -1);
    }

    /**
     * Add header view to mHeaderLayout and set header view position in mHeaderLayout.
     * When index = -1 or index >= child count in mHeaderLayout,
     * the effect of this method is the same as that of {@link #addHeaderView(View)}.
     *
     * @param header
     * @param index  the position in mHeaderLayout of this header.
     *               When index = -1 or index >= child count in mHeaderLayout,
     *               the effect of this method is the same as that of {@link #addHeaderView(View)}.
     */
    public int addHeaderView(View header, int index) {
        return addHeaderView(header, index, LinearLayout.VERTICAL);
    }

    /**
     * @param header
     * @param index
     * @param orientation
     */
    public int addHeaderView(View header, int index, int orientation) {
        if (mNormalHeaderLayout == null) {
            mNormalHeaderLayout = new LinearLayout(header.getContext());
            if (orientation == LinearLayout.VERTICAL) {
                mNormalHeaderLayout.setOrientation(LinearLayout.VERTICAL);
                mNormalHeaderLayout.setLayoutParams(new RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
            } else {
                mNormalHeaderLayout.setOrientation(LinearLayout.HORIZONTAL);
                mNormalHeaderLayout.setLayoutParams(new RecyclerView.LayoutParams(WRAP_CONTENT, MATCH_PARENT));
            }
        }
        final int childCount = mNormalHeaderLayout.getChildCount();
        if (index < 0 || index > childCount) {
            index = childCount;
        }
        mNormalHeaderLayout.addView(header, index);
        if (mNormalHeaderLayout.getChildCount() == 1) {
            int position = getNormalHeaderViewPosition();
            if (position != -1) {
                notifyItemInserted(position);
            }
        }
        return index;
    }

    public int setHeaderView(View header) {
        return setHeaderView(header, 0, LinearLayout.VERTICAL);
    }

    public int setHeaderView(View header, int index) {
        return setHeaderView(header, index, LinearLayout.VERTICAL);
    }

    public int setHeaderView(View header, int index, int orientation) {
        if (mNormalHeaderLayout == null || mNormalHeaderLayout.getChildCount() <= index) {
            return addHeaderView(header, index, orientation);
        } else {
            mNormalHeaderLayout.removeViewAt(index);
            mNormalHeaderLayout.addView(header, index);
            return index;
        }
    }

    /**
     * remove header view from mHeaderLayout.
     * When the child count of mHeaderLayout is 0, mHeaderLayout will be set to null.
     *
     * @param header
     */
    public void removeNormalHeaderView(View header) {
        if (getNormalHeaderLayoutCount() == 0)
            return;

        mNormalHeaderLayout.removeView(header);
        if (mNormalHeaderLayout.getChildCount() == 0) {
            int position = getNormalHeaderViewPosition();
            if (position != -1) {
                notifyItemRemoved(position);
            }
        }
    }

    /**
     * remove all header view from mHeaderLayout and set null to mHeaderLayout
     */
    public void removeAllNormalHeaderView() {
        if (getNormalHeaderLayoutCount() == 0)
            return;

        mNormalHeaderLayout.removeAllViews();
        int position = getNormalHeaderViewPosition();
        if (position != -1) {
            notifyItemRemoved(position);
        }
    }

    /**
     * Append footer to the rear of the mFooterLayout.
     *
     * @param footer
     */
    public int addFooterView(View footer) {
        return addFooterView(footer, -1, LinearLayout.VERTICAL);
    }

    public int addFooterView(View footer, int index) {
        return addFooterView(footer, index, LinearLayout.VERTICAL);
    }

    /**
     * Add footer view to mFooterLayout and set footer view position in mFooterLayout.
     * When index = -1 or index >= child count in mFooterLayout,
     * the effect of this method is the same as that of {@link #addFooterView(View)}.
     *
     * @param footer
     * @param index  the position in mFooterLayout of this footer.
     *               When index = -1 or index >= child count in mFooterLayout,
     *               the effect of this method is the same as that of {@link #addFooterView(View)}.
     */
    public int addFooterView(View footer, int index, int orientation) {
        if (mNormalFooterLayout == null) {
            mNormalFooterLayout = new LinearLayout(footer.getContext());
            if (orientation == LinearLayout.VERTICAL) {
                mNormalFooterLayout.setOrientation(LinearLayout.VERTICAL);
                mNormalFooterLayout.setLayoutParams(new RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
            } else {
                mNormalFooterLayout.setOrientation(LinearLayout.HORIZONTAL);
                mNormalFooterLayout.setLayoutParams(new RecyclerView.LayoutParams(WRAP_CONTENT, MATCH_PARENT));
            }
        }
        final int childCount = mNormalFooterLayout.getChildCount();
        if (index < 0 || index > childCount) {
            index = childCount;
        }
        mNormalFooterLayout.addView(footer, index);
        if (mNormalFooterLayout.getChildCount() == 1) {
            int position = getFooterViewPosition();
            if (position != -1) {
                notifyItemInserted(position);
            }
        }
        return index;
    }

    public int setFooterView(View header) {
        return setFooterView(header, 0, LinearLayout.VERTICAL);
    }

    public int setFooterView(View header, int index) {
        return setFooterView(header, index, LinearLayout.VERTICAL);
    }

    public int setFooterView(View header, int index, int orientation) {
        if (mNormalFooterLayout == null || mNormalFooterLayout.getChildCount() <= index) {
            return addFooterView(header, index, orientation);
        } else {
            mNormalFooterLayout.removeViewAt(index);
            mNormalFooterLayout.addView(header, index);
            return index;
        }
    }

    /**
     * remove footer view from mFooterLayout,
     * When the child count of mFooterLayout is 0, mFooterLayout will be set to null.
     *
     * @param footer
     */
    public void removeFooterView(View footer) {
        if (getNormalFooterLayoutCount() == 0)
            return;

        mNormalFooterLayout.removeView(footer);
        if (mNormalFooterLayout.getChildCount() == 0) {
            int position = getFooterViewPosition();
            if (position != -1) {
                notifyItemRemoved(position);
            }
        }
    }

    /**
     * remove all footer view from mFooterLayout and set null to mFooterLayout
     */
    public void removeAllFooterView() {
        if (getNormalFooterLayoutCount() == 0)
            return;

        mNormalFooterLayout.removeAllViews();
        int position = getFooterViewPosition();
        if (position != -1) {
            notifyItemRemoved(position);
        }
    }


    private int getNormalHeaderViewPosition() {
        //Return to header view notify position
        if (getEmptyViewCount() == 1) {
            return 0;
        }
        return -1;
    }

    private int getFooterViewPosition() {
        //Return to footer view notify position
        if (getEmptyViewCount() == 1) {
            int position = 1;
            if (getNormalHeaderLayoutCount() != 0) {
                return position++;
            }
        } else {
            return getNormalHeaderLayoutCount() + mDatas.size();
        }
        return -1;
    }

    /**
     * if show empty view will be return 1 or not will be return 0
     *
     * @return
     */
    public int getEmptyViewCount() {
        if (mEmptyLayout == null || mEmptyLayout.getChildCount() == 0) {
            return 0;
        }

        if (mDatas.size() != 0) {
            return 0;
        }
        return 1;
    }

    /**
     * 是否是正常头布局
     *
     * @param position
     * @return
     */
    private boolean isNormalHeaderView(int position) {
        return position < getNormalHeaderLayoutCount();
    }

    /**
     * 是否是加载更多FooterView
     *
     * @param position
     * @return
     */
    private boolean isLoadMoreFooterView(int position) {
        return mLoadMoreEnable && position >= getItemCount() - getLoadMoreFooterLayoutCount();
    }

    /**
     * 是否是FooterView
     *
     * @param position
     * @return
     */
    private boolean isNormalFooterView(int position) {
        return position == getItemCount() - getNormalFooterLayoutCount() - getLoadMoreFooterLayoutCount();
    }

    /**
     * 返回 footer view数量 (是否有脚布局)
     *
     * @return
     */
    public int getLoadMoreFooterViewCount() {
        if (!mLoadMoreEnable || mLoadMoreFooterLayout == null || mLoadMoreFooterLayout.getChildCount() == 0) {
            return 0;
        }

        if (mDatas.size() == 0) {
            return 0;
        }

        return 1;
    }

    /**
     * if addHeaderView will be return 1, if not will be return 0
     */
    public int getNormalHeaderLayoutCount() {
        if (mNormalHeaderLayout == null || mNormalHeaderLayout.getChildCount() == 0) {
            return 0;
        }
        return 1;
    }

    /**
     * if addFooterView will be return 1, if not will be return 0
     */
    public int getNormalFooterLayoutCount() {
        if (mNormalFooterLayout == null || mNormalFooterLayout.getChildCount() == 0) {
            return 0;
        }
        return 1;
    }

    /**
     * 子view
     * if addFooterView will be return 1, if not will be return 0
     */
    public int getLoadMoreFooterLayoutCount() {
        if (mLoadMoreFooterLayout == null || mLoadMoreFooterLayout.getChildCount() == 0) {
            return 0;
        }
        return 1;
    }


    /**
     * Set the enabled state of load more.
     *
     * @param enable True if load more is enabled, false otherwise.
     */
    public void setEnableLoadMore(boolean enable) {
        mLoadMoreEnable = enable;
        isLoading = !enable;


        if (mLoadMoreEnable) {
            if (mLoadingView == null) {
                //加载更多数 , 更新footer view提示
                setLoadingView(R.layout.load_loading_layout);
            } else {
                setLoadingView(mLoadingView);
            }
            notifyItemInserted(getItemCount());
        } else if (getLoadMoreFooterLayoutCount() > 0) {
            notifyItemRemoved(getItemCount());
            removeLoadMoreFooterView();
        }
    }

    public static final int STATUS_DEFAULT = 1;//一直显示加载完成
    public static final int STATUS_END_SHOW_GONE = 2;//显示1秒后隐藏 , 持续显示与隐藏
    public static final int STATUS_END_GONE = 3;//隐藏加载完成布局

    /**
     * Refresh end, no more data , gone Load more
     */
    public void loadMoreEnd() {
        loadMoreEnd(STATUS_DEFAULT);
    }

    /**
     * Refresh end, no more data
     *
     * @param loadMoreStatus show the load more view status
     */
    public void loadMoreEnd(int loadMoreStatus) {

        if (loadMoreStatus != STATUS_END_GONE) {
            if (mLoadEndView == null) {
                //加载完成,更新footer view提示
                setLoadEndView(R.layout.load_end_layout);
            }
            addLoadMoreFooterView(mLoadEndView);
        }
        switch (loadMoreStatus) {
            case STATUS_DEFAULT:
                goneLoadingMore = false;
                break;
            case STATUS_END_SHOW_GONE:
                goneLoadingMore = true;
                if (goneLoadingMore) {
                    mHandler.postDelayed(mMyThread, 500);
                }
                break;
            case STATUS_END_GONE:
                removeLoadMoreFooterView();
                break;
        }
    }

    /**
     * Refresh complete
     */
    public void loadMoreComplete() {
        isLoading = false;
        notifyItemRemoved(getItemCount());
    }

    /**
     * 数据加载失败
     */
    public void loadFailed() {
        if (mLoadFailedView == null) {
            //加载失败,更新footer view提示
            setLoadFailedView(R.layout.load_failed_layout);
        }
        addLoadMoreFooterView(mLoadFailedView);

        mLoadFailedView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                addLoadMoreFooterView(mLoadingView);
                if (mLoadMoreListener != null) {
                    mLoadMoreListener.onLoadMore(true);
                }
            }
        });
    }

    /**
     * 获得列表数据个数
     *
     * @return
     */
    public int getDataCount() {
        return mDatas.size();
    }

    protected List<T> getAllData() {
        return mDatas;
    }

    /**
     * 下拉刷新,得到的新数据插入到原数据头部
     *
     * @param datas
     */
    public void setRefreshData(List<T> datas) {
        setRefreshData(0, datas);
    }

    /**
     * 得到的新数据插入到某个位置
     *
     * @param datas
     */
    public void setRefreshData(int position, List<T> datas) {
        mDatas.addAll(position, datas);
        notifyItemRangeInserted(position, datas.size());

        //        notifyDataSetChanged();
    }

    /**
     * 初次加载、或下拉刷新要替换全部旧数据时刷新数据
     *
     * @param datas
     */
    public void setNewData(List<T> datas) {
        //        if (isReset) {
        //            isReset = false;
        //        }
        isLoading = false;
        mDatas.clear();
        mDatas.addAll(datas);
        notifyDataSetChanged();
    }

    /**
     * 插入数据  从就的数据的位置开始  到新数据的数量大小的位置
     *
     * @param datas
     */
    public void addData(List<T> datas) {
        isLoading = false;
        mDatas.addAll(datas);
        notifyItemRangeInserted(mDatas.size() - datas.size() + getNormalHeaderLayoutCount(), datas.size());
    }

    /**
     * 刷新加载更多的数据
     *
     * @param datas
     */
    public void setLoadMoreData(List<T> datas) {
        isLoading = false;
        int size = mDatas.size();
        mDatas.addAll(datas);
        notifyItemInserted(size + getNormalHeaderLayoutCount());
    }

以上就是核心代码 如有不懂的 可以直接去github 下载源码 

或者加入安卓开发交流群:安卓帮595856941

相关链接:

下一篇:

安卓开发之recyclerview的BaseAdapter的简单封装(二)(优化篇之条目子view的点击事件)

安卓框架搭建(一)基本配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值