大概說下原理:
1.利用ListView的footer,來顯示提示信息比如:正在加載中,也可以換成圖標,或者自定義的控件;
2.利用OnScrollListener,滾動條監聽器,判斷滾動條滾動到底部的時候,設置listview的footer,在開啓子線程加載數據,數據加載完畢後通知listview的adapter更新界面,在移除footer。
先上效果圖:
MainActivity.java
package com.example.list;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnScrollListener{
ListView listView;
List<Map<String,String>> list = new ArrayList();
MyAdapter adapter;
//底部footer
View footer;
//最大頁數
int maxPage = 5;
//當前頁數
int page = 1;
//每頁顯示數
int pageSize = 20;
//是否加載數據中
boolean isLoading = false;
//Toast顯示狀態
boolean isToast = false;
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
if(msg.what == 1){
//得到消息中的數據
list.addAll((List)msg.obj);
//告訴適配器,數據變化了,從新加載listview
adapter.notifyDataSetChanged();
//移除底部footer
listView.removeFooterView(footer);
//當前頁數增加
page++;
//設置加載中爲false
isLoading = false;
}else if(msg.what == 0){
//設置加載中爲false
isToast = false;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.lv);
footer = LayoutInflater.from(this).inflate(R.layout.footer, null);
list = DataService.getData(pageSize, page);
adapter = new MyAdapter(this, list);
//添加footer必須在setAdapter之前,不然會顯示不出來
listView.addFooterView(footer);
listView.setAdapter(adapter);
listView.setOnScrollListener(this);
listView.removeFooterView(footer);
}
/**
* 滾動條狀態,1是滑動,0是靜止
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
// if(SCROLL_STATE_TOUCH_SCROLL == scrollState){
// System.out.println("SCROLL_STATE_TOUCH_SCROLL "+scrollState );
// }else if(SCROLL_STATE_IDLE == scrollState){
// System.out.println("SCROLL_STATE_IDLE "+scrollState );
// }
}
/**
* 監聽移動滾動條
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// 如果正在加載,就return,防止加載多次
if(isLoading)
return;
// 得到listview中顯示在界面底部的id
int lastItemid = listView.getLastVisiblePosition();
// 如果是listview中顯示在界面底部的id=滾動條中Item總數,說明滑動到底部了,並且當前頁<=總頁數
if((lastItemid+1) == totalItemCount && page <= maxPage){
if(page == maxPage){//到最後一頁,提示(此方法有bug,會提示多次,,加個線程會好一點,但是還不能完全解決)
if(!isToast){
isToast = true;
Toast.makeText(this, "沒有更多的數據了...", 0).show();
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendMessage(handler.obtainMessage(0, null));
}
}.start();
}
return;
}
//設置正在加載中
isLoading = true;
if(totalItemCount > 0){
//現在底部footer
listView.addFooterView(footer);
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List list = DataService.getData(pageSize, page+1);
handler.sendMessage(handler.obtainMessage(1, list));
}
}.start();
}
}
//System.out.println("firstVisibleItem:"+firstVisibleItem+" visibleItemCount:"+visibleItemCount+" totalItemCount:"+totalItemCount);
}
}
MyAdapter.java
package com.example.mylistview;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter{
List<Map<String,String>> list;
Context context;
public MyAdapter(Context context,List list){
this.context = context;
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list, null);
viewHolder.id = (TextView) convertView.findViewById(R.id.id);
viewHolder.name = (TextView) convertView.findViewById(R.id.name);
viewHolder.phone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder)convertView.getTag();
}
// 設置應用名稱
Map<String,String> map = list.get(position);
viewHolder.id.setText(map.get("id"));
viewHolder.name.setText(map.get("name"));
viewHolder.phone.setText(map.get("phone"));
return convertView;
}
private static class ViewHolder {
public TextView id,name,phone;
}
}
dataService.java
package com.example.mylistview;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DataService {
public static List<Map<String,String>> getData(int pageSize,int page){
List<Map<String,String>> list = new ArrayList();
int index = (pageSize*(page-1)+1);
int max = pageSize * page;
for(int i = index; i <= max; i++){
Map<String,String> map = new HashMap();
map.put("id", "ID:"+i);
map.put("name", "姓名:"+i);
map.put("phone", "電話:"+i);
list.add(map);
}
return list;
}
}
源碼免費下載:http://download.csdn.net/download/qq247300948/7497127