1、略过实现ListView的item布局以及主布局,用于footerView的布局xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv001"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/use_life"/>
</LinearLayout>
2、定义了一个存储数据的单独的java文件模型类(并不规范):
package com.example.dhasa.studydemo;
/**
* Created by dhasa on 2016/3/24.
*/
public class News {
String title;
String content;
}
3、实现分页的ListView的activity如下:
package com.example.dhasa.studydemo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.Vector;
/**
* @author dhasa
* 1、首先按照之前的方法实现listview;(数据后期模仿网络请求,单独定义一个类来存储数据)
* 2、定义一个用于footerview的布局并且添加到listview中;
* 3、定义一个子线程用来模仿网络请求服务器中剩余分页中的数据;
* 4、实现listview的OnScrollListener,并且实现他的两个方法:
* (1)onScrollStateChanged判断滑动状态的方法;三个状态:正在滚动、停止、手未离开屏幕(touch)滚动
* (2)onScroll计算滑动位置(第几个item)的方法
* 不仅滚动停止并且已经滚动到屏幕最底下才会出现加载字样
* 5、当4中最后一句满足时,启动线程,线程中数据进行更新。
* 6、线程中数据更新(模仿的数据请求到)后,利用定义的handler发送空消息(只带有消息标记)
* 给主UI线程中的Handler实例去handleMessage,通过switch去判断消息的标记类型,由主线程自己去改变adapter。
*/
public class Main3Activity extends Activity implements AbsListView.OnScrollListener{
private ListView lv;
private Vector<News> news = new Vector<>();
private int index = 1;
private MyAdapter myAdapter;
private int visableLastIndex;//最后一个可见的item的索引
private static final int DATA_UPDATE = 0X1;//数据更新完成后的标记
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
lv = (ListView) findViewById(R.id.lv3);
View view = getLayoutInflater().inflate(R.layout.loading,null);
lv.addFooterView(view);
initData();
//纯粹是为了用myAdapter调用notifyDataSetChanged()方法而去定义一个adapter实例
myAdapter = new MyAdapter(getApplicationContext());
lv.setAdapter(myAdapter);
lv.setOnScrollListener(this);//注册滑动监听事件
}
private void initData(){
for(int i=0;i<10;i++){
News n = new News();
n.content = "content--"+index;
n.title = "title--"+index;
index++;
news.add(n);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==AbsListView.OnScrollListener.SCROLL_STATE_IDLE
&& myAdapter.getCount() == visableLastIndex){
new LoadDataTread().start();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
visableLastIndex = firstVisibleItem + visibleItemCount - 1;
}
//线程之间通信用handler机制
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case DATA_UPDATE:
myAdapter.notifyDataSetChanged();//主线程得到通知,自己去更新adapter
break;
}
}
};
//子线程不能直接访问主线程(UI线程),Adapter使用在ListView中,属于UI线程的一部分
class LoadDataTread extends Thread{
@Override
public void run() {
initData();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// myAdapter.notifyDataSetChanged();会发生线程错误!!!
//子线程通过handler给主线程发送消息标记(无消息empty),通知主线程数据更新完成
handler.sendEmptyMessage(DATA_UPDATE);//相当于各司其职的两部分,我的部分完成告诉另一部分
}
}
class MyAdapter extends BaseAdapter{
private LayoutInflater mInflater;
public MyAdapter(Context context){
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return news.size();
}
@Override
public Object getItem(int position) {
return news.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh;
if(convertView==null){
convertView = mInflater.inflate(R.layout.list_item3,null);
vh = new ViewHolder();
vh.title = (TextView)convertView.findViewById(R.id.title3);
vh.content = (TextView) convertView.findViewById(R.id.content3);
convertView.setTag(vh);
}else{
vh = (ViewHolder) convertView.getTag();
}
vh.title.setText(news.get(position).title);
vh.content.setText(news.get(position).content);
return convertView;
}
}
private class ViewHolder{
TextView title;
TextView content;
}
}
handler机制:线程间通信