ListView上拉加载更多

1 原理图: ListView在滑动的时候,会不断的传递三个值,这三个值为:

1 int firstVisibleItem

2 int visibleItemCount

3 int totalItemCount

ListView上拉加载更多_第1张图片

2 监听ListView的滑动事件

1 实现OnScrollListener接口

public class MListView extends ListView implements OnScrollListener

覆写两个方法:

@Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}

2 onScroll()方法

第一个方法是判断onScroll方法是判断是否滑动到底部的重点,我们上拉加载更多的操作在这里完成。

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    if (firstVisibleItem + visibleItemCount == totalItemCount) {
        Log.i(TAG, "add more");
        if (callBack != null && !loading) {
            callBack.onAddMore();
            loading = true;
        }
    }
}

在这里设置一个回调接口,将加载更多数据的耗时操作交给接口。

interface MCallBack { void onAddMore(); }
private MCallBack callBack;
public void setCallBack(MCallBack callBack) {
    this.callBack = callBack;
}

在这里还有一个loading标识符,当开始加载更多的时候,无法再次上拉进行加载。
所以这里也要设置一个对外的方法,当加载完成之后,把loading复位。

public void setLoading(boolean loading) {
    this.loading = loading;
}

3 onScrollStateChanged()方法

这个方法是判断用户滑动的模式,源码中有提到:

 /**
 * The view is not scrolling. Note navigating the list using the trackball counts as
 * being in the idle state since these transitions are not animated.
 */
public static int SCROLL_STATE_IDLE = 0;

/**
 * The user is scrolling using touch, and their finger is still on the screen
 */
public static int SCROLL_STATE_TOUCH_SCROLL = 1;

/**
 * The user had previously been scrolling using touch and had performed a fling. The
 * animation is now coasting to a stop
 */
public static int SCROLL_STATE_FLING = 2;

1 SCROLL_STATE_IDLE 表示缓慢的滑动

2 SCROLL_STATE_TOUCH_SCROLL 表示正常的滑动

3 SCROLL_STATE_FLING 表示飞快的滑动

这里不多做讨论

4 addFooterView()方法

作用:加载更多,可以用一个菊花或者文字表示 “正在加载”,这个View就放在FooterView当中。

这个方法,在4.4版本之前的API中,只能在设置适配器之前调用。

而在4.4或者更高版本的API中,可以在任意地方调用。

footerView的布局:




    


5 初始化方法:

private void initInflater(Context context) {
    mInflater = LayoutInflater.from(context);
    footerView = mInflater.inflate(R.layout.view4addmore, null);
    addFooterView(footerView);
    setOnScrollListener(this);
}

6 完整代码:

package com.pullupaddmore.main;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.AbsListView.OnScrollListener;
import com.granton.pullupaddmore.R;

public class MListView extends ListView implements OnScrollListener {

    private static final String TAG = "MListView";
    private LayoutInflater mInflater;
    private View footerView;

    private void initInflater(Context context) {
        mInflater = LayoutInflater.from(context);
        footerView = mInflater.inflate(R.layout.view4addmore, null);
        addFooterView(footerView);
        setOnScrollListener(this);
    }

    public MListView(Context context) {
        super(context);
        initInflater(context);
    }

    public MListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initInflater(context);
    }

    public MListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initInflater(context);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    private boolean loading = false;

    public void setLoading(boolean loading) {
        this.loading = loading;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        if (firstVisibleItem + visibleItemCount == totalItemCount) {
            Log.i(TAG, "add more");
            if (callBack != null && !loading) {
                callBack.onAddMore();
                loading = true;
            }
        }
    }

    public void setCallBack(MCallBack callBack) {
        this.callBack = callBack;
    }

    private MCallBack callBack;

    interface MCallBack {
        void onAddMore();
    }
}

3 实际使用:

1 在Activity或者Fragment的布局文件中加入:


2 获取ListView 绑定数据源:

getData();
mListView = (MListView) findViewById(R.id.listview);
mListView.setCallBack(MainActivity.this);
adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
mListView.setAdapter(adapter);

获取数据源getData():

private void getData() {
    list.add("new---------new1");
    list.add("2---------2new");
    list.add("3-----new----3");
    list.add("4-------new--4");
    list.add("5-----new----5");
    list.add("6-------new--6");
    list.add("7----new-----7");
    list.add("8-------new--8");
    list.add("9---------9new");
    list.add("10-new--------10");
    list.add("11----new-----11");
    list.add("12-------new--12");
    list.add("13---new------13");
}

3 activity实现ListView中的回调接口:

加载更多数据这类操作一定要放在子线程中

否则会引起界面卡顿或者直接报错

并且使用Handler来处理数据在界面上的更新。

public class MainActivity extends Activity implements MCallBack

@Override
public void onAddMore() {
    new Thread() {
        public void run() {
            try {
                Thread.sleep(2 * 1000);
                list.add("1---------1");
                list.add("2---------2");
                list.add("3---------3");
                list.add("4---------4");
                list.add("5---------5");
                list.add("6---------6");
                list.add("7---------7");
                list.add("8---------8");
                list.add("9---------9");
                list.add("10---------10");
                list.add("11---------11");
                handler.sendEmptyMessage(0);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();
}

4 Handler:

private Handler handler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
        case 0:
            adapter.notifyDataSetChanged();
            mListView.setLoading(false);
            break;
        default:
            break;
        }
    };
};

你可能感兴趣的:(ListView上拉加载更多)