在上一篇中,我們實現了底部布局(即帶上了進度條)。沒有讀過的朋友可以點擊下面的鏈接:
http://www.cnblogs.com/fuly550871915/p/4866966.html
但是進度條的消失,以及數據的加載我們都沒有實現,那么在本節中,我們來完成分頁加載。具體的效果我就不貼圖了,就是第一篇效果展示的那些效果。
代碼還是 有些難度。需要用到回調接口,實現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了。運行吧,看看分頁加載到底是什么效果!