ListView实现分页
实现过程:
效果图:
数据来源:
模拟新闻,在主布局中添加一个ListView组件, 每一个列表项显示两个组件 ,这里显示两个文本信息,
布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView6_title"
android:layout_width="wrap_content"
android:textSize="20dp"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:text="title" />
<TextView
android:id="@+id/textView6_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"
android:layout_marginLeft="10dp"
android:text="content" />
</LinearLayout>
将要显示的数据封装在一个新闻类中如下:
public class News {
String title;
String content;
}
各组件的声明:
private ListView listView;
private Vector<News> nws = new Vector<>();
private MyAdapter myAdapter;
private final static int DATA_UPDATE = 0x1;//数据更新完场后的标志
如下为数据的初始化:
private void intData() {
for (int i = 0; i <= 20; i++) {
News n = new News();
n.title = "奥巴马访问中国" + index;
n.content = "美国总统奥巴马于北京时间8:00抵达北京,开始了为期三天的中美会谈" + index;
index++;
nws.add(n);
}
}
一:在ListView初始化的时候加个footview ,初始化相关变量以及要设置listview的OnScrllLitener :
如下:
listView = (ListView) findViewById(R.id.listView6);
listView.setOnScrollListener(this);
View view = getLayoutInflater().inflate(R.layout.head_loadring, null);
listView.addFooterView(view);
intData();// 初始化数据
myAdapter = new MyAdapter();
listView.setAdapter(myAdapter);
二 :数据加载
加载数据的时候使用一个新线程加载,完成之后使用handler发送消息,重新渲染列表项
这里就要使用Adapter中所带的notifiyDataSetChange
notifiyDataSetChange 方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容,可以实现动态的刷新列表的功能。
如下 开启新线程模拟重新加载数据
class LoadDateThread extends Thread {
@Override
public void run() {
intData();
try {
Thread.sleep(2000);// 加载慢点
} catch (InterruptedException e) {
e.printStackTrace();
}
// 通过Handler给主线程发送消息标记
handler.sendEmptyMessage(DATA_UPDATE);
}
}
数据加载完毕后,需要通知UI线程重新绘制,线程之间的通信使用Handler来完成
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case DATA_UPDATE:
//通知主线程数据更新完毕
myAdapter.notifyDataSetChanged();
break;
}
}
};
在OnScroIIListener中检测是否滑动到最后一个列表项
private int visibleLastIndex; //可显示的最后一条数据的索引值
@Override
//状态改变(空闲,滚动,触摸状态)
/* SCROLL_STATE_IDLE (空闲状态没有滚动)
SCROLL_STATE_FLING (正在滚动)
SCROLL_STATE_TOUCH_SCROLL(触摸状态)
*/
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (myAdapter.getCount() == visibleLastIndex && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE ) {
new LoadDateThread().start();
}
}
@Override
//滚动时触发该方法
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
visibleLastIndex = firstVisibleItem + visibleItemCount - 1;
}
//线程之间进行通信的机制
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case DATA_UPDATE:
//通知主线程数据更新完毕
myAdapter.notifyDataSetChanged();
break;
}
}
};
完整代码如下:
public class Main6Activity extends AppCompatActivity implements AbsListView.OnScrollListener {
private ListView listView;
private Vector<News> nws = new Vector<>();
private MyAdapter myAdapter;
private final static int DATA_UPDATE = 0x1;//数据更新完场后的标志
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main6);
listView = (ListView) findViewById(R.id.listView6);
listView.setOnScrollListener(this);
View view = getLayoutInflater().inflate(R.layout.head_loadring, null);
listView.addFooterView(view);
intData();// 初始化数据
myAdapter = new MyAdapter();
listView.setAdapter(myAdapter);
}
private int index = 1;
/*
初始化数据
*/
private void intData() {
for (int i = 0; i <= 20; i++) {
News n = new News();
n.title = "奥巴马访问中国" + index;
n.content = "美国总统奥巴马于北京时间8:00抵达北京,开始了为期三天的中美会谈" + index;
index++;
nws.add(n);
}
}
private int visibleLastIndex; //可显示的最后一条数据的索引值
@Override
//状态改变(空闲,滚动,触摸状态)
/* SCROLL_STATE_IDLE (空闲状态没有滚动)
SCROLL_STATE_FLING (正在滚动)
SCROLL_STATE_TOUCH_SCROLL(触摸状态)
*/
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (myAdapter.getCount() == visibleLastIndex && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE ) {
new LoadDateThread().start();
}
}
@Override
//滚动时触发该方法
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
visibleLastIndex = firstVisibleItem + visibleItemCount - 1;
}
//线程之间进行通信的机制
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case DATA_UPDATE:
//通知主线程数据更新完毕
myAdapter.notifyDataSetChanged();
break;
}
}
};
// 开启新线程模拟重新加载数据
class LoadDateThread extends Thread {
@Override
public void run() {
intData();
try {
Thread.sleep(2000);// 加载慢点
} catch (InterruptedException e) {
e.printStackTrace();
}
// 通过Handler给主线程发送消息标记
handler.sendEmptyMessage(DATA_UPDATE);
}
}
// 自定义适配器
class MyAdapter extends BaseAdapter { // 子线程
@Override
public int getCount() {
return nws.size();
}
@Override
public Object getItem(int position) {
return nws.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 = getLayoutInflater().inflate(R.layout.item_6, null);
vh = new ViewHolder();
vh.tv_title = (TextView) convertView.findViewById(R.id.textView6_title);
vh.tv_content = (TextView) convertView.findViewById(R.id.textView6_content);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
News n = nws.get(position);
vh.tv_title.setText(n.title);
vh.tv_content.setText(n.content);
return convertView;
}
class ViewHolder {
TextView tv_title;
TextView tv_content;
}
}
}