上下拉实现刷新和加载更多的ListView,如下:

package com.sin.android.ui;import android.content.Context;import android.util.AttributeSet;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;/** * 动态刷新和加载数据ListView * @author RobinTang * */public class DynamicListView extends ListView implements OnScrollListener {/** * 监听器 * 监听控件的刷新或者加载更多事件 * 所有的条目事件都会有一个偏移量,也就是position应该减1才是你适配器中的条目 * @author RobinTang * */public interface DynamicListViewListener {/** *  * @param dynamicListView * @param isRefresh 为true的时候代表的是刷新,为false的时候代表的是加载更多 * @return true:刷新或者加载更多动作完成,刷新或者加载更多的动画自动消失 false:刷新或者加载更多为完成,需要在数据加载完成之后去调用控件的doneRefresh()或者doneMore()方法  */public boolean onRefreshOrMore(DynamicListView dynamicListView, boolean isRefresh);}/** * 状态控件(StatusView,列表头上和底端的)的状态枚举 * @author RobinTang * */enum RefreshStatus {none, normal, willrefresh, refreshing}/** * 状态控件 * @author RobinTang * */class StatusView extends LinearLayout {public int height;public int width;private ProgressBar progressBar = null;private TextView textView = null;private RefreshStatus refreshStatus = RefreshStatus.none;private String normalString = "下拉刷新";private String willrefreshString = "松开刷新";private String refreshingString = "正在刷新";public StatusView(Context context, AttributeSet attrs) {super(context, attrs);initThis(context);}public StatusView(Context context) {super(context);initThis(context);}private void initThis(Context context) {this.setOrientation(LinearLayout.HORIZONTAL);this.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);progressBar = new ProgressBar(context);progressBar.setLayoutParams(new LinearLayout.LayoutParams(30, 30));textView = new TextView(context);textView.setPadding(5, 0, 0, 0);this.addView(progressBar);this.addView(textView);int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);this.measure(w, h);height = this.getMeasuredHeight();width = this.getMeasuredWidth();this.setRefreshStatus(RefreshStatus.normal);}public RefreshStatus getRefreshStatus() {return refreshStatus;}public void setRefreshStatus(RefreshStatus refreshStatus) {if (this.refreshStatus != refreshStatus) {this.refreshStatus = refreshStatus;if(refreshStatus == RefreshStatus.refreshing){this.progressBar.setVisibility(View.VISIBLE);}else{this.progressBar.setVisibility(View.GONE);}refreshStatusString();this.invalidate();}}private void refreshStatusString() {switch (refreshStatus) {case normal:textView.setText(normalString);progressBar.setProgress(0);break;case willrefresh:textView.setText(willrefreshString);break;case refreshing:textView.setText(refreshingString);break;default:break;}}/** * 设置状态字符串 * @param normalString平时的字符串 * @param willrefreshString松开后刷新(或加载)的字符串 * @param refreshingString正在刷新(或加载)的字符串 */public void setStatusStrings(String normalString, String willrefreshString, String refreshingString){this.normalString = normalString;this.willrefreshString = willrefreshString;this.refreshingString = refreshingString;this.refreshStatusString();}}private StatusView refreshView;private StatusView moreView;private int itemFlag = -1;private boolean isRecorded = false;private int downY = -1;private final float minTimesToRefresh = 1.5f;private final static int ITEM_FLAG_FIRST = 1;private final static int ITEM_FLAG_NONE = 0;private final static int ITEM_FLAG_LAST = -1;// 两个监听器private DynamicListViewListener onRefreshListener;private DynamicListViewListener onMoreListener;// 滚动到低端的时候是否自动加载更多private boolean doMoreWhenBottom = false;public DynamicListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initThis(context);}public DynamicListView(Context context, AttributeSet attrs) {super(context, attrs);initThis(context);}public DynamicListView(Context context) {super(context);initThis(context);}private void initThis(Context context) {refreshView = new StatusView(context);moreView = new StatusView(context);refreshView.setStatusStrings("继续下拉刷新数据...", "松开之后刷新数据...", "正在刷新数据...");moreView.setStatusStrings("继续上拉加载数据...", "松开之后加载数据...", "正在加载数据...");this.addHeaderView(refreshView, null, false);this.addFooterView(moreView, null, false);this.setOnScrollListener(this);doneRefresh();doneMore();}// 监听器操作public DynamicListViewListener getOnRefreshListener() {return onRefreshListener;}public void setOnRefreshListener(DynamicListViewListener onRefreshListener) {this.onRefreshListener = onRefreshListener;}public DynamicListViewListener getOnMoreListener() {return onMoreListener;}public void setOnMoreListener(DynamicListViewListener onMoreListener) {this.onMoreListener = onMoreListener;}// 设置public boolean isDoMoreWhenBottom() {return doMoreWhenBottom;}public void setDoMoreWhenBottom(boolean doMoreWhenBottom) {this.doMoreWhenBottom = doMoreWhenBottom;}@Overridepublic void onScroll(AbsListView l, int t, int oldl, int count) {// log("%d %d %d", t, oldl, count);if (t == 0)itemFlag = ITEM_FLAG_FIRST;else if ((t + oldl) == count){itemFlag = ITEM_FLAG_LAST;if(doMoreWhenBottom && onMoreListener != null && moreView.getRefreshStatus() != RefreshStatus.refreshing){doMore();}}else {itemFlag = ITEM_FLAG_NONE;//isRecorded = false;}}@Overridepublic void onScrollStateChanged(AbsListView arg0, int arg1) {}@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:if (isRecorded == false && (itemFlag == ITEM_FLAG_FIRST && onRefreshListener != null && refreshView.getRefreshStatus() == RefreshStatus.normal || itemFlag == ITEM_FLAG_LAST && onMoreListener != null && moreView.getRefreshStatus() == RefreshStatus.normal)) {downY = (int) ev.getY(0);isRecorded = true;//log("按下,记录:%d flag:%d", downY, itemFlag);}break;case MotionEvent.ACTION_UP: {isRecorded = false;if (onRefreshListener != null && refreshView.getRefreshStatus() == RefreshStatus.willrefresh) {doRefresh();} else if (refreshView.getRefreshStatus() == RefreshStatus.normal) {refreshView.setPadding(0, -1 * refreshView.height, 0, 0);}if (onMoreListener != null && moreView.getRefreshStatus() == RefreshStatus.willrefresh) {doMore();} else if (moreView.getRefreshStatus() == RefreshStatus.normal) {moreView.setPadding(0, 0, 0, -1 * moreView.height);}break;}case MotionEvent.ACTION_MOVE: {if (isRecorded == false && (itemFlag == ITEM_FLAG_FIRST && onRefreshListener != null && refreshView.getRefreshStatus() == RefreshStatus.normal || itemFlag == ITEM_FLAG_LAST && onMoreListener != null && moreView.getRefreshStatus() == RefreshStatus.normal)) {downY = (int) ev.getY(0);isRecorded = true;//log("按下,记录:%d flag:%d", downY, itemFlag);} else if (isRecorded) {int nowY = (int) ev.getY(0);int offset = nowY - downY;if (offset > 0 && itemFlag == ITEM_FLAG_FIRST) {// 下拉setSelection(0);if (offset >= (minTimesToRefresh * refreshView.height)) {refreshView.setRefreshStatus(RefreshStatus.willrefresh);} else {refreshView.setRefreshStatus(RefreshStatus.normal);}refreshView.setPadding(0, -1 * (refreshView.height - offset), 0, 0);} else if(itemFlag == ITEM_FLAG_LAST){// 上拉setSelection(this.getCount());if (offset <= -1 * (minTimesToRefresh * moreView.height)) {moreView.setRefreshStatus(RefreshStatus.willrefresh);} else {moreView.setRefreshStatus(RefreshStatus.normal);}moreView.setPadding(0, 0, 0, -1 * (moreView.height + offset));}//log("位移:%d", offset);}break;}default:break;}return super.onTouchEvent(ev);}/** * 开始刷新 */private void doRefresh(){//log("开始刷新");refreshView.setRefreshStatus(RefreshStatus.refreshing);refreshView.setPadding(0, 0, 0, 0);if(onRefreshListener.onRefreshOrMore(this, true))doneRefresh();}/** * 开始加载更多 */private void doMore(){//log("加载更多");moreView.setRefreshStatus(RefreshStatus.refreshing);moreView.setPadding(0, 0, 0, 0);if(onMoreListener.onRefreshOrMore(this, false))doneMore();}/** * 刷新完成之后调用,用于取消刷新的动画 */public void doneRefresh() {//log("刷新完成!");refreshView.setRefreshStatus(RefreshStatus.normal);refreshView.setPadding(0, -1 * refreshView.height, 0, 0);}/** * 加载更多完成之后调用,用于取消加载更多的动画 */public void doneMore() {//log("加载完成!");moreView.setRefreshStatus(RefreshStatus.normal);moreView.setPadding(0, 0, 0, -1 * moreView.height);}/** * 获取刷新的状态 * @return一般 将要刷新 刷新完成 */public RefreshStatus getRefreshStatus(){return refreshView.getRefreshStatus();}/** * 获取加载更多的状态 * @return一般 将要加载 加载完成 */public RefreshStatus getMoreStatus(){return moreView.getRefreshStatus();}//private void log(Object obj) {//log("%s", obj.toString());//}////private void log(String format, Object... args) {//Log.i("DynamicListView", String.format(format, args));//}}

使用例子:

package com.sin.android.ui;import java.util.ArrayList;import java.util.Date;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ArrayAdapter;import android.widget.Toast;import com.sin.android.ui.DynamicListView.DynamicListViewListener;@SuppressLint("HandlerLeak")public class MainActivity extends Activity implements DynamicListViewListener {DynamicListView listView;ArrayList<String> data;ArrayAdapter<String> adapter;// 用于刷新控件状态Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == 0) {adapter.notifyDataSetChanged();listView.doneRefresh();Toast.makeText(MainActivity.this, "新加载"+msg.arg1+"条数据!", Toast.LENGTH_LONG).show();} else if (msg.what == 1) {adapter.notifyDataSetChanged();listView.doneMore();} else {super.handleMessage(msg);}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);listView = new DynamicListView(this);setContentView(listView);data = new ArrayList<String>();for (int i = 1; i < 10; ++i) {data.add("原始数据" + i);}adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, data);listView.setAdapter(adapter);listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {Log.i("",data.get(arg2-1));}});listView.setDoMoreWhenBottom(false);// 滚动到低端的时候不自己加载更多listView.setOnRefreshListener(this);listView.setOnMoreListener(this);}@Overridepublic boolean onRefreshOrMore(DynamicListView dynamicListView, boolean isRefresh) {if (isRefresh) {new Thread(new Runnable() {@Overridepublic void run() {// 刷新ArrayList<String> temp = new ArrayList<String>();for (int i = 0; i < 3; ++i) {temp.add(0, new Date().toLocaleString());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}synchronized (data) {data.addAll(0, temp);}Message message = new Message();message.what = 0;message.arg1 = temp.size();handler.sendMessage(message);}}).start();} else {new Thread(new Runnable() {@Overridepublic void run() {// 加载更多ArrayList<String> temp = new ArrayList<String>();for (int i = 0; i < 3; ++i) {temp.add(new Date().toLocaleString());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}synchronized (data) {data.addAll(temp);}handler.sendEmptyMessage(1);}}).start();}return false;}}


截图:

Android ListView列表 刷新和加载更多_第1张图片

Android ListView列表 刷新和加载更多_第2张图片


Android ListView列表 刷新和加载更多_第3张图片

Android ListView列表 刷新和加载更多_第4张图片



更多相关文章

  1. PullToRefreshLayout +RecyclerView 实现上拉加载下拉刷新
  2. 图片加载的几种模式
  3. ImageView下载图片加载
  4. Android 利用TCP通信 实现环境数据显示及控制指令下发
  5. Android 动态加载(三) - 类的加载流程源码分析
  6. Android 动态加载(二) - 基础篇(二)
  7. Android数据加密之Rsa加密
  8. 数据显示Android“姜饼”系统用户数增多
  9. android中的数据库操作

随机推荐

  1. Android(安卓)WebView 和 手机后退按钮
  2. Activity的启动模式
  3. Android中的控件
  4. Android(安卓)Handler机制理解
  5. Android(安卓)滑动手势侦测方法介绍
  6. win7下修改AVD默认路径
  7. Android工程中R.java文件的重新生成——
  8. RK3399: 支持wifi/4g与以太网共存
  9. Android事件分发之dispatchTouchEvent()
  10. [Android]自定义Button之drawableLeft居