ListView的下拉刷新和上拉加载(一)

今天说一说ListView的下拉刷新和上拉加载的初步实现,感觉自己写的东西基本上就是拾人牙慧,几乎没什么创新,就是把别人的东西东拼西凑来实现自己的需求。但是还是能学到点东西的,至少以后自己再遇到同样的请求可以看自己的总结就行了。

下拉刷新参考网址:github地址https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh

上拉加载参考网址https://segmentfault.com/a/1190000004292874
先看一看效果

下拉刷新就不说了,下面说一说上拉加载实现的原理。

  1. ListView 实现上拉加载更多,就是在ListView在滚动的时候,并且竖直方向上向上滚动的距离大于0,当最后一个iten可见的时候触发加载更多的操作。请注意滚动距离大于0 这两个条件,因为如果ListView 初始化的时候只有很少几项数据,这时候,最后item是可见的。这时候,ListView的滚动距离为0,所以不应该触发加载更多操作。
  2. 在加载更多的过程中,动态给ListView添加一个footView,footview有两种状态,正在加载,和没有更多数据。
  3. 在加载完成后,如果得到的数据不为空,就通知adapter notifyDataSetChanged(),然后把footview隐藏或者remove。如果得到的数据为空,footview就应该显示 no more data 类似的提示。
  4. 实现的步骤最主要的是给ListView添加一个滚动的监听事件,当ListView滚动的时候,判断是否满足加载更多的条件,如果满足,就加载更多。接下来看看自定义LsitView源码并不难理解
package com.example.listviewpulldownrefreshpulluploadmore;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;

/**
 * Created by dumingwei on 2016/8/20.
 */
public class MyListView extends ListView {

    private boolean isPullUpLoading = false;//是否正在加载更多
    private boolean noMoreItem = false;//是否还有更多数据
    private LoadMoreListener loadMoreListener;//加载更多的回调接口

    public void setNoMoreItem(boolean noMoreItem) {
        this.noMoreItem = noMoreItem;
    }


    private PullUpLoadListViewFooter mFooterView;


    public void setPullUpLoading(boolean pullUpLoading) {
        isPullUpLoading = pullUpLoading;
    }

    public void setLoadMoreListener(LoadMoreListener loadMoreListener) {
        this.loadMoreListener = loadMoreListener;
    }

    public MyListView(Context context) {
        this(context, null);
    }

    public MyListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

//在初始化中给ListView 添加滚动时候的监听
    private void init() {
        isPullUpLoading = false;
        mFooterView = new PullUpLoadListViewFooter(getContext());
        //添加自定义的滚动监听MyOnScrollerListener
        setOnScrollListener(new MyOnScrollerListener());
    }
//自定义的滚动监听MyOnScrollerListener
    private class MyOnScrollerListener implements OnScrollListener {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            //do nothing here
        }

        /**
        在这里进行判断和执行加载更多的操作
         * Callback method to be invoked when the list or grid has been scrolled. This will be called after the scroll has completed
         * @param firstVisibleItem the index of the first visible cell (ignore if visibleItemCount == 0)
         * @param visibleItemCount the number of visible cells
         * @param totalItemCount   the number of items in the list adaptor
         */
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
/**
 * 判断条件表示的意思
 * !isPullUpLoading 不是处于正在加载更多的状态中
 * (firstVisibleItem + visibleItemCount) == totalItemCount ,ListView的最后一个item可见
 *  getScrollDistance() > 0 ,ListView 向上滑动的距离大于0(如果不加这个条件,当ListView最初只有几项数据,以至于,前两个条件满足,会触发加载更多操作)
 */
            if (!isPullUpLoading && !noMoreItem && (firstVisibleItem + visibleItemCount) == totalItemCount && getScrollDistance() > 0) {
                showFootView();
                if (loadMoreListener != null) {
                    loadMoreListener.loadMore();
                }
            }
        }
    }

    /**
     * 计算ListView 在竖直方向上的滑动距离
     *
     * @return
     */
    public int getScrollDistance() {
        View c = getChildAt(0);
        if (c == null) {
            return 0;
        }
        int firstVisiblePosition = getFirstVisiblePosition();
        int top = c.getTop();
        return -top + firstVisiblePosition * c.getHeight();
    }

    /**
     * 加载更多的回调接口
     */
    public interface LoadMoreListener {
        void loadMore();
    }

    /**
     * 显示footView
     */
    public void showFootView() {
        if (getFooterViewsCount() < 1) {
            addFooterView(mFooterView);
        }
        mFooterView.setVisibility(View.VISIBLE);
        mFooterView.updateView(PullUpLoadListViewFooter.State.LOADING);//显示Loading
    }

    /**
     * 隐藏掉footView
     */
    public void removeFootView() {
        setPullUpLoading(false);
        // removeFooterView(mFooterView);
        mFooterView.setVisibility(View.GONE);
    }

    /**
     * 数据已经完全加载完毕,footView 显示 no  more
     */
    public void haveLoadAll() {
        setNoMoreItem(true);//没有更多数据
        if (mFooterView != null) {
            mFooterView.setVisibility(View.VISIBLE);
            mFooterView.updateView(PullUpLoadListViewFooter.State.NOT_LOADING);//显示no more data
        }

    }
}

该说的都在注释里面了,使用的demo下载,请移步https://github.com/humanheima/ListViewPullDownRefreshPullUpLoadMore

你可能感兴趣的:(菜鸟博客)