1. ListView分页加载实现思路
实现OnScrollListener 接口重写onScrollStateChanged 和onScroll方法,使用onscroll方法实现”滑动“后处理检查是否还有新的记录,如果有,调用 addFooterView,添加记录到adapter, adapter调用 notifyDataSetChanged 更新数据;如果没有记录了,把自定义的mFooterView去掉。使用onScrollStateChanged可以检测是否滚到最后一行且停止滚动然后执行加载。
1 [java] view plaincopyprint? 2 import android.app.ListActivity; 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.view.Gravity; 6 import android.view.View; 7 import android.view.ViewGroup; 8 import android.widget.AbsListView; 9 import android.widget.BaseAdapter; 10 import android.widget.ImageView; 11 import android.widget.LinearLayout; 12 import android.widget.ProgressBar; 13 import android.widget.TextView; 14 import android.widget.AbsListView.OnScrollListener; 15 import android.widget.LinearLayout.LayoutParams; 16 public class Test extends ListActivity implements OnScrollListener { 17 Aleph0 adapter = new Aleph0(); 18 int lastItem = 0; 19 int mProgressStatus = 0; 20 private Handler mHandler = new Handler(); 21 ProgressBar progressBar; 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 LinearLayout searchLayout = new LinearLayout(this); 25 searchLayout.setOrientation(LinearLayout.HORIZONTAL); 26 progressBar = new ProgressBar(this); 27 progressBar.setPadding(0, 0, 15, 0); 28 searchLayout.addView(progressBar,new LinearLayout.LayoutParams( 29 LinearLayout.LayoutParams.WRAP_CONTENT, 30 LinearLayout.LayoutParams.WRAP_CONTENT 31 )); 32 TextView textView = new TextView(this); 33 textView.setText("加载中..."); 34 textView.setGravity(Gravity.CENTER_VERTICAL); 35 searchLayout.addView(textView,new LinearLayout.LayoutParams( 36 LinearLayout.LayoutParams.FILL_PARENT, 37 LinearLayout.LayoutParams.FILL_PARENT 38 )); 39 searchLayout.setGravity(Gravity.CENTER); 40 LinearLayout loadingLayout = new LinearLayout(this); 41 loadingLayout.addView(searchLayout,new LinearLayout.LayoutParams( 42 LinearLayout.LayoutParams.WRAP_CONTENT, 43 LinearLayout.LayoutParams.WRAP_CONTENT 44 )); 45 loadingLayout.setGravity(Gravity.CENTER); 46 getListView().addFooterView(loadingLayout); 47 // Start lengthy operation in a background thread 48 // new Thread(new Runnable() { 49 // public void run() { 50 // while (mProgressStatus < 100) { 51 // 52 // // Update the progress bar 53 // mHandler.post(new Runnable() { 54 // public void run() { 55 // progressBar.setProgress(mProgressStatus); 56 // } 57 // }); 58 // } 59 // } 60 // }).start(); 61 registerForContextMenu(getListView()); 62 setListAdapter(adapter); 63 getListView().setOnScrollListener(this); 64 } 65 public void onScroll(AbsListView v, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 66 lastItem = firstVisibleItem + visibleItemCount - 1 ; 67 System.out.println("lastItem:" + lastItem); 68 } 69 public void onScrollStateChanged(AbsListView v, int state) { 70 if(lastItem == adapter.count && state == OnScrollListener.SCROLL_STATE_IDLE){ 71 adapter.count += 10; 72 adapter.notifyDataSetChanged(); 73 } 74 // if(state == OnScrollListener.SCROLL_STATE_IDLE ) { 75 // adapter.count += 10; 76 // adapter.notifyDataSetChanged(); 77 // } 78 } 79 class Aleph0 extends BaseAdapter { 80 int count = 10; 81 public int getCount() { return count; } 82 public Object getItem(int pos) { return pos; } 83 public long getItemId(int pos) { return pos; } 84 public View getView(int pos, View v, ViewGroup p) { 85 TextView view = new TextView(Test.this); 86 view.setText("entry " + pos); 87 view.setHeight(90); 88 return view; 89 } 90 } 91 }
第二种。
1 package com.notice.moredate; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.os.Handler; 9 import android.view.View; 10 import android.view.View.OnClickListener; 11 import android.widget.AbsListView; 12 import android.widget.AbsListView.OnScrollListener; 13 import android.widget.Button; 14 import android.widget.ListView; 15 import android.widget.ProgressBar; 16 import android.widget.SimpleAdapter; 17 import android.widget.Toast; 18 19 public class MoreDateListActivity extends Activity implements OnScrollListener { 20 21 // ListView的Adapter 22 private SimpleAdapter mSimpleAdapter; 23 private ListView lv; 24 private Button bt; 25 private ProgressBar pg; 26 private ArrayList<HashMap<String,String>> list; 27 // ListView底部View 28 private View moreView; 29 private Handler handler; 30 // 设置一个最大的数据条数,超过即不再加载 31 private int MaxDateNum; 32 // 最后可见条目的索引 33 private int lastVisibleIndex; 34 35 /** Called when the activity is first created. */ 36 @Override 37 public void onCreate(Bundle savedInstanceState) { 38 super.onCreate(savedInstanceState); 39 setContentView(R.layout.main); 40 41 42 MaxDateNum = 22; // 设置最大数据条数 43 44 lv = (ListView) findViewById(R.id.lv); 45 46 // 实例化底部布局 47 moreView = getLayoutInflater().inflate(R.layout.moredate, null); 48 49 bt = (Button) moreView.findViewById(R.id.bt_load); 50 pg = (ProgressBar) moreView.findViewById(R.id.pg); 51 handler = new Handler(); 52 53 // 用map来装载数据,初始化10条数据 54 list = new ArrayList<HashMap<String,String>>(); 55 for (int i = 0; i < 10; i++) { 56 HashMap<String, String> map = new HashMap<String, String>(); 57 map.put("ItemTitle", "第" + i + "行标题"); 58 map.put("ItemText", "第" + i + "行内容"); 59 list.add(map); 60 } 61 // 实例化SimpleAdapter 62 mSimpleAdapter = new SimpleAdapter(this, list, R.layout.item, 63 new String[] { "ItemTitle", "ItemText" }, 64 new int[] { R.id.tv_title, R.id.tv_content }); 65 // 加上底部View,注意要放在setAdapter方法前 66 lv.addFooterView(moreView); 67 lv.setAdapter(mSimpleAdapter); 68 // 绑定监听器 69 lv.setOnScrollListener(this); 70 71 bt.setOnClickListener(new OnClickListener() { 72 73 @Override 74 public void onClick(View v) { 75 pg.setVisibility(View.VISIBLE);// 将进度条可见 76 bt.setVisibility(View.GONE);// 按钮不可见 77 78 handler.postDelayed(new Runnable() { 79 80 @Override 81 public void run() { 82 loadMoreDate();// 加载更多数据 83 bt.setVisibility(View.VISIBLE); 84 pg.setVisibility(View.GONE); 85 mSimpleAdapter.notifyDataSetChanged();// 通知listView刷新数据 86 } 87 88 }, 2000); 89 } 90 }); 91 92 } 93 94 private void loadMoreDate() { 95 int count = mSimpleAdapter.getCount(); 96 if (count + 5 < MaxDateNum) { 97 // 每次加载5条 98 for (int i = count; i < count + 5; i++) { 99 HashMap<String, String> map = new HashMap<String, String>(); 100 map.put("ItemTitle", "新增第" + i + "行标题"); 101 map.put("ItemText", "新增第" + i + "行内容"); 102 list.add(map); 103 } 104 } else { 105 // 数据已经不足5条 106 for (int i = count; i < MaxDateNum; i++) { 107 HashMap<String, String> map = new HashMap<String, String>(); 108 map.put("ItemTitle", "新增第" + i + "行标题"); 109 map.put("ItemText", "新增第" + i + "行内容"); 110 list.add(map); 111 } 112 } 113 114 } 115 116 @Override 117 public void onScroll(AbsListView view, int firstVisibleItem, 118 int visibleItemCount, int totalItemCount) { 119 // 计算最后可见条目的索引 120 lastVisibleIndex = firstVisibleItem + visibleItemCount - 1; 121 122 // 所有的条目已经和最大条数相等,则移除底部的View 123 if (totalItemCount == MaxDateNum + 1) { 124 lv.removeFooterView(moreView); 125 Toast.makeText(this, "数据全部加载完成,没有更多数据!", Toast.LENGTH_LONG).show(); 126 } 127 128 } 129 130 @Override 131 public void onScrollStateChanged(AbsListView view, int scrollState) { 132 // 滑到底部后自动加载,判断listview已经停止滚动并且最后可视的条目等于adapter的条目 133 if (scrollState == OnScrollListener.SCROLL_STATE_IDLE 134 && lastVisibleIndex == mSimpleAdapter.getCount()) { 135 // 当滑到底部时自动加载 136 // pg.setVisibility(View.VISIBLE); 137 // bt.setVisibility(View.GONE); 138 // handler.postDelayed(new Runnable() { 139 // 140 // @Override 141 // public void run() { 142 // loadMoreDate(); 143 // bt.setVisibility(View.VISIBLE); 144 // pg.setVisibility(View.GONE); 145 // mSimpleAdapter.notifyDataSetChanged(); 146 // } 147 // 148 // }, 2000); 149 150 } 151 152 } 153 154 }