在上一篇中,我们实现了底部布局(即带上了进度条)。没有读过的朋友可以点击下面的链接:
但是进度条的消失,以及数据的加载我们都没有实现,那么在本节中,我们来完成分页加载。具体的效果我就不贴图了,就是第一篇效果展示的那些效果。
代码还是 有些难度。需要用到回调接口,实现ListView的下拉监听等知识以及判断何时进度条出现何时消失等。
陈述一下具体逻辑吧。首先在initView中,我们不仅要加上底布局,还应该时底布局消失。然后我们实现ListView的OnScrollListener接口,监听它的滚动。在其中的一个方法onScroll,我们可以获得到当前第一个可见item的编号以及当前有多少个可见item和总共有多少个item。这样子我们就可以轻易由计算得出是否滚动带最底部了。然后在onSrollStateChanged方法中做判断,如果滚动到最底部,就显示出正在加载数据的进度条,并完成数据的加载。但是有一个问题是,加载的数据在MainActivity里面,我们怎么在MyListView中获得加载的数据?这就要使用接口回调,我们在MyListView中设定一个回调接口,然后在MainAcivty中回调,就可以实现MyListView获得加载的数据。 好了,大体逻辑就是这样子的,剩下的就是细节上的逻辑了。我们看代码,注释解释的也很清楚了。如下:
1 package com.fuly.load;
2
3 import android.content.Context;
4 import android.util.AttributeSet;
5 import android.view.LayoutInflater;
6 import android.view.View;
7 import android.widget.AbsListView;
8 import android.widget.AbsListView.OnScrollListener;
9 import android.widget.ListView;
10
11 public class MyListView extends ListView implements OnScrollListener{
12
13 private int lastVisibleItem;//最后一个可见的item
14
15 private int totalItemCount;//总的item
16
17 private boolean isLoading = false;//是否正在加载数据
18
19 private ILoadListener mListener;//回调接口,用来加载数据
20
21 private View footer;//底布局
22
23
24 //注意,三个构造方法都要重写
25 public MyListView(Context context) {
26 super(context);
27 initView(context);
28
29 }
30 public MyListView(Context context, AttributeSet attrs) {
31 super(context, attrs);
32 initView(context);
33 }
34 public MyListView(Context context, AttributeSet attrs, int defStyle) {
35 super(context, attrs, defStyle);
36 initView(context);
37 }
38
39
40 //定义一个回调接口,用来获得要加载的数据
41 public interface ILoadListener{
42 void loadData();
43 }
44
45 public void setOnILoadListener(ILoadListener listener){
46
47 this.mListener = listener;
48 }
49
50
51
52 //初始化view
53 private void initView(Context context){
54
55 footer = LayoutInflater.from(context).inflate(R.layout.footer, null);
56
57 //注意,这句代码的意思是给自定义的ListView加上底布局
58 this.addFooterView(footer);
59
60 //首先需要隐藏这个底部布局
61 footer.findViewById(R.id.load_layout).setVisibility(View.GONE);
62
63 this.setOnScrollListener(this);//千万别忘记设定监听器
64
65 }
66
67
68
69 //加载数据完成后,需要执行的操作
70 public void loadFinish(){
71
72 isLoading = false;//不再加载了
73 //底布局也要隐藏
74 footer.findViewById(R.id.load_layout).setVisibility(View.GONE);
75
76 }
77
78
79 //参数scrollState表示滑动的状态
80 public void onScrollStateChanged(AbsListView view, int scrollState) {
81
82 //如果最后一个可见item等于总的item,且当前滚动状态为滚动停止,就应该开始加加载数据了
83 if(lastVisibleItem == totalItemCount && scrollState==SCROLL_STATE_IDLE){
84
85 if(!isLoading){
86 isLoading = true;
87
88 //加载数据
89 mListener.loadData();
90 //设置底布局可见
91 footer.findViewById(R.id.load_layout).setVisibility(View.VISIBLE);
92 }
93 }
94
95 }
96
97 /***
98 * 该方法用来监听实时滚动中的item
99 * firstVisibleItem:当前第一个可见的item
100 * visibleItemCount:当前总共有多少个可见的item
101 * totalItemCount:总的item
102 */
103 public void onScroll(AbsListView view, int firstVisibleItem,
104 int visibleItemCount, int totalItemCount) {
105
106 this.lastVisibleItem = firstVisibleItem + visibleItemCount;
107 this.totalItemCount = totalItemCount;
108
109 }
110
111
112
113 }
然后我们再修改MainActivity中的代码即可,如下:
1 package com.fuly.load;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import com.fuly.load.MyListView.ILoadListener;
7
8 import android.os.Bundle;
9 import android.os.Handler;
10 import android.app.Activity;
11
12
13
14 public class MainActivity extends Activity implements ILoadListener{
15
16 private MyListView lv;
17 private List<MyData> mDatas = new ArrayList<MyData>();
18 private MyAdapter mAdapter;
19
20
21 protected void onCreate(Bundle savedInstanceState) {
22 super.onCreate(savedInstanceState);
23 setContentView(R.layout.activity_main);
24
25 initData();//该方法初始化数据
26 lv = (MyListView) findViewById(R.id.list_view);
27 lv.setOnILoadListener(this);
28 mAdapter = new MyAdapter(this, mDatas);
29 lv.setAdapter(mAdapter);
30
31
32 }
33
34
35 /**
36 * 该方法初始化数据,即提供初始的素材
37 */
38 private void initData() {
39 for(int i = 0;i<12;i++){
40 MyData md = new MyData("你好,我是提前设定的");
41 mDatas.add(md);
42 }
43
44 }
45
46 /**
47 * 该方法提供模拟的加载数据
48 */
49 private void getLoadData() {
50 for(int i = 0;i<3;i++){
51 MyData md = new MyData("你好,我是加载进来的");
52 mDatas.add(md);
53 }
54
55 }
56
57
58
59 //重写回调方法
60 public void loadData() {
61
62 //注意之所以使用Handlder,主要是想让下面的
63 //操作延迟5秒钟,以体现效果。实际开发中不需要
64 Handler mHandler = new Handler();
65 mHandler.postDelayed(new Runnable(){
66
67
68 public void run() {
69
70 //获得加载数据
71 getLoadData();
72 //然后通知MyListView刷新界面
73 mAdapter.notifyDataSetChanged();
74
75 //然后通知加载数据已经完成了
76
77 lv.loadFinish();
78 }
79
80 }, 5000);
81
82
83 }
84
85 }
好了,一切都OK了。运行吧,看看分页加载到底是什么效果!