標籤:
- 概念清晰後,具體實現的部分到了。這裡實現的下拉載入效果(個人感覺很不錯,簡潔明了),大概需要以下幾個步驟:
- first — 首先構建下拉載入時的底部載入布局(這裡命名為view_more)
- second — 擷取資料並給listView設定adapter;設定好adapter後,調用方法:
listView.addFooterView(view_more);// TODO 添加底部記載布局再往listView的底部添加底部載入布局。最後對listView設定滑動監聽器:listView.setOnScrollListener(this);// TODO listView這是滑動監聽 並重寫相關方法:
public void onScrollStateChanged(AbsListView view, int scrollState) {} 和 public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {} 這兩個重寫的方法一個是監聽listView的滑動狀態改變,另一個是監聽listView的滑動。
- third — 當滑動監聽設定好後,在重寫的兩個方法裡面判斷listView是否滑動到底部並且停止滑動(即滑動狀態為停止滑動)。如果此時滿足這個條件,那麼就載入更多的資料。資料載入完成後就重新整理資料來源,此時會有更多的資料在底部出現。
- fourth — 最後當資料全部載入好後,移除第二步中添加的底部載入布局view_more,調用方法:
listView.removeFooterView(view_more);// TODO 移除底部的載入布局
下面寫代碼一步一步來實現:
- 1、首先準備一個底部載入布局,命名為view_more
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="80dp" android:background="#8888" > <TextView android:id="@+id/tv_Load" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="正在載入..." android:textSize="14sp" android:visibility="visible" /> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@id/tv_Load" android:padding="10dp" android:visibility="visible" /></RelativeLayout>
很簡單的布局,顯示了一個進度條和一個文本控制項。
- 第二,給listView設定資料並設定滑動監聽,設定好後判斷是否滑動到listView的底部並停止滑動,如果是那麼載入更多的資料:
package com.example.drop_down_load;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;public class MainActivity extends Activity implements OnScrollListener { private ListView listView; private int totalCount;// 資料總條數 private List<String> lists = new ArrayList<String>(); private ArrayAdapter<String> adapter; // 建立handler接收訊息並處理訊息 private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case 0: // 建立adapter adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, lists); // 設定adapter listView.setAdapter(adapter); // 添加底部載入布局 listView.addFooterView(view_more); // 設定監聽 setListeners(); break; } }; }; private View view_more; private ProgressBar pb; private TextView tvLoad; private int lastVisibleIndex; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 控制項初始化 initViews(); // 初始化資料 initData(); } private void initData() { // 類比網路請求擷取資料,一次擷取15條 new Thread() { public void run() { try { totalCount = 100;// 假設資料一共有100條,將來調介面可以擷取到這個值 for (int i = 0; i < 15; i++) { lists.add("資料" + (i + 1)); } // 給handler發訊息更新UI,子線程不可以更新UI Message message = new Message(); message.what = 0; handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } }; }.start(); } private void setListeners() { if (totalCount > 15) { // listView設定滑動簡監聽 listView.setOnScrollListener(this); } else { // 假如資料總數少於等於15條,直接移除底部的載入布局,不需要再載入更多的資料 listView.removeFooterView(view_more); } } private void initViews() { listView = (ListView) findViewById(R.id.listView); // 構建底部載入布局 view_more = (View) getLayoutInflater() .inflate(R.layout.view_more, null); // 進度條 pb = (ProgressBar) view_more.findViewById(R.id.progressBar); // “正在載入...”文本控制項 tvLoad = (TextView) view_more.findViewById(R.id.tv_Load); } /** * 監聽listView的滑動狀態的改變 */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.e("TAG", "lastVisibleIndex = " + lastVisibleIndex); Log.e("TAG", "adapter.getCount() = " + adapter.getCount()); // 滑到底部後自動載入,判斷listView已經停止滾動並且最後可視的條目等於adapter的條目 // 注意這裡在listView設定好adpter後,加了一個底部載入布局。 // 所以判斷條件為:lastVisibleIndex == adapter.getCount() if (scrollState == SCROLL_STATE_IDLE && lastVisibleIndex == adapter.getCount()) { /** * 這裡也要設定為可見,是因為當你真正從網路擷取資料且擷取失敗的時候。 * 我在失敗的方法裡面,隱藏了底部的載入布局並提示使用者載入失敗。所以再次監聽的時候需要 * 繼續顯示隱藏的控制項。因為我類比的擷取資料,失敗的情況這裡不給出。實際中簡單的加上幾句代碼就行了。 */ pb.setVisibility(View.VISIBLE); tvLoad.setVisibility(View.VISIBLE); loadMoreData();// 載入更多資料 } } private void loadMoreData() { } /** * 監聽listView的滑動 */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // 計算最後可見條目的索引 lastVisibleIndex = firstVisibleItem + visibleItemCount - 1; // 當adapter中的所有條目數已經和要載入的資料總條數相等時,則移除底部的View if (totalItemCount == totalCount + 1) { // 移除底部的載入布局 listView.removeFooterView(view_more); } }}
以上代碼就是我上面步驟2和步驟2中所說的東西。加上我寫了注釋,所以相信大家看起來很簡單。關鍵點是怎麼判斷listView是否滑動到了底部並停止了滑動。我在代碼中添加了兩行log,可以列印日誌資訊。大家去自己調試就能明白我對關鍵點是怎麼判斷的了,但是也有聰明的!嘿嘿!大家都懂,自己人,我就不接話了。
- 最後就是載入更多的資料了,即完成第二步中未完成的方法:
loadMoreData();// 載入更多資料
具體代碼實現為:
private void loadMoreData() { // 擷取此時adapter中的總條目數 int count = adapter.getCount(); // 一次載入15條資料,即下拉載入的執行 if (count + 15 < totalCount) { start = count; end = start + 15; initData(start, end);// 類比網路擷取資料操作 } else {// 資料不足15條直接載入到結束 start = count; end = totalCount; initData(start, end);// 類比網路擷取資料曹祖 // 資料全部載入完成後,移除底部的view listView.removeFooterView(view_more); Toast.makeText(MainActivity.this, "資料已經全部載入", 1).show(); } }private void initData(final int start, final int end) { // 類比網路請求擷取資料,一次擷取15條 new Thread() { public void run() { try { Thread.sleep(4000);// 類比擷取資料時的耗時3s for (int i = start; i < end; i++) { lists.add(i, "資料" + (i + 1)); } // 給handler發訊息更新UI,子線程不可以更新UI Message message = new Message(); message.what = 1; handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } }; }.start(); }
此時handler中還要再加一個case語句,用來重新整理資料來源,紅色方框標註地方,大家自己加一下。最後我會給項目源碼,大家可以下載看My Code:
好了下面給出幾張項目的展示圖片:
談談我的感悟:你需要有自己的想法思路,別人的東西可以借鑒,但是你需要從中學到點什麼。要是什麼都沒學到,那就失去了分享的意義了!分享是為了讓大家學到更多,收穫更多。希望我的這篇能夠給大家一點點收穫!
項目的源碼:點擊我下載項目源碼
每天進步一點點!加油!
Android中listView的下拉載入功能實現