Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中listView的下拉加載功能實現

Android中listView的下拉加載功能實現

編輯:關於Android編程

今天給大家講講android開發中比較常見的listView的下拉加載,其實也可以叫做分頁加載。為什麼會有這個叫法呢?說說我的理解吧!

從字面上很好理解。當你滑動一個列表到底部的時候,這個時候就會出現正在加載的底部加載布局去加載更多的數據。這裡拿微信作為一個例子,如下圖所示:

這裡寫圖片描述vcTjus3F89PRt6K1xNK70KnXtMysoaPV4srH0vLOqtXiuPbKsbrytPrC69Do0qq4+Lf+zvHG97eiy83H68fzu/HIocr9vt2yorPKz9bV4tCpyv2+3aGj1eK49sqxuvK78cihyv2+3b7Ns8nBy9fuusTKsbXEzsrM4qGjzqrKssO01eLDtMu1o7/I57n7w7vT0LfW0rO809TYtcS5psTco6zEx8O0o6zE47/PtqjQ6NKqu/HIocirsr+1xMr9vt2jrMTjv8nS1M/rz+ujrLrDvLjE6rXEyv2+3aOsyv2+3cG/v8myu8nZsKGjobeix+vH88ilu/HIodXi0KnK/b7dsqKzys/Wy/zDx8rHu+G63LrEyrG85LXEoaPL+dLUt9bSs7zT1Ni+zbrcusO1xL3ivvbBy9XiuPbOyszioaPE48/Iu/HIocbk1tC1xMquvLjM9cr9vt2yorPKz9bL/MPHoaO1scTj0rvWsbTTzbfkr8DA1eLKrry4zPXK/b7dtb294cr4tcTKsbryo6zV4rj2yrG68tTZyKW809TYuPy24LXEyv2+3bKis8rP1sv8w8eho8jnyc/NvMv5yr6jrNXi0fmyxcrHusO1xNPDu6fM5dHpoaM8L3A+DQo8aHIgLz4NCrjFxO7H5c76uvOjrL7fzOXKtc/WtcSyv7fWtb3By6Gj1eLA78q1z9bOotDFtcTPwsCtvNPU2NCnufujqLj2yMu40L71utyyu7Tto6y88r3gw/fBy6Opo6y087jF0OjSqtLUz8K8uLj2sr3W6KO6PGJyIC8+DQpmaXJzdCAmbWRhc2g7IMrXz8i5ub2oz8LArbzT1NjKsbXEtdeyv7zT1NiyvL7Wo6jV4sDvw/zD+86qdmlld19tb3Jlo6kgc2Vjb25kICZtZGFzaDsgu/HIocr9vt2yorj4bGlzdFZpZXfJ6NbDYWRhcHRlcqO7yejWw7rDYWRhcHRlcrrzo6y199PDt723qKO6PGNvZGU+bGlzdFZpZXcuYWRkRm9vdGVyVmlldyh2aWV3X21vcmUpOy8vIFRPRE8gzO2807XXsr+8x9TYsry+1jwvY29kZT7U2c35bGlzdFZpZXe1xLXXsr/M7bzTtdeyv7zT1NiyvL7WoaPX7rrzttRsaXN0Vmlld8no1sO7rLavvODM/cb3o7o8Y29kZT5saXN0Vmlldy5zZXRPblNjcm9sbExpc3RlbmVyKHRoaXMpOy8vIFRPRE8gbGlzdFZpZXfV4srHu6y2r7zgzP08L2NvZGU+ILKi1tjQtM/gudi3vbeoo7o8YnIgLz4NCjxjb2RlPnB1YmxpYyB2b2lkIG9uU2Nyb2xsU3RhdGVDaGFuZ2VkKEFic0xpc3RWaWV3IHZpZXcsIGludCBzY3JvbGxTdGF0ZSkge308L2NvZGU+ILrNIDxjb2RlPnB1YmxpYyB2b2lkIG9uU2Nyb2xsKEFic0xpc3RWaWV3IHZpZXcsIGludCBmaXJzdFZpc2libGVJdGVtLGludCB2aXNpYmxlSXRlbUNvdW50LCBpbnQgdG90YWxJdGVtQ291bnQpIHt9PC9jb2RlPiDV4sG9uPbW2NC0tcS3vbeo0ru49srHvODM/Wxpc3RWaWV3tcS7rLav17TMrLjEseSjrMHt0ru49srHvODM/Wxpc3RWaWV3tcS7rLavoaMgdGhpcmQgJm1kYXNoOyC1sbustq+84Mz9yejWw7rDuvOjrNTa1tjQtLXEwb249re9t6jA78PmxdC2z2xpc3RWaWV3yse38bustq+1vbXXsr+yosfSzaPWubustq+jqLy0u6y2r9e0zKzOqs2j1rm7rLavo6mho8jnufu0y8qxwvrX49XiuPbM9bz+o6zEx8O0vs2809TYuPy24LXEyv2+3aGjyv2+3bzT1NjN6rPJuvO+zcui0MLK/b7d1LSjrLTLyrG74dPQuPy24LXEyv2+3dTatdeyv7P2z9ahoyBmb3VydGggJm1kYXNoOyDX7rrztbHK/b7dyKuyv7zT1Ni6w7rzo6zSxrP9tdq2/rK91tDM7bzTtcS117K/vNPU2LK8vtZ2aWV3X21vcmWjrLX308O3vbeoo7o8Y29kZT5saXN0Vmlldy5yZW1vdmVGb290ZXJWaWV3KHZpZXdfbW9yZSk7Ly8gVE9ETyDSxrP9tdeyv7XEvNPU2LK8vtY8L2NvZGU+DQo8aDQgaWQ9"下面寫代碼一步一步來實現">下面寫代碼一步一步來實現: 1、首先准備一個底部加載布局,命名為view_more




    

    

很簡單的布局,顯示了一個進度條和一個文本控件。如圖:

這裡寫圖片描述

第二,給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 lists = new ArrayList();
    private ArrayAdapter adapter;
    // 創建handler接收消息並處理消息
    private Handler handler = new Handler() {

        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case 0:
                // 創建adapter
                adapter = new ArrayAdapter(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語句,用來刷新數據源,如圖紅色方框標注地方,大家自己加一下。最後我會給項目源碼,大家可以下載看我的代碼:

這裡寫圖片描述

好了下面給出幾張項目的展示圖片:

15條數據後加載更多數據,如圖:

這裡寫圖片描述

30條數據後加載更多數據,如圖:

這裡寫圖片描述

45條數據後加載更多數據,如圖:

這裡寫圖片描述

數據全部加載完後,移除底部加載布局,如圖:

這裡寫圖片描述

談談我的感悟:你需要有自己的想法思路,別人的東西可以借鑒,但是你需要從中學到點什麼。要是什麼都沒學到,那就失去了分享的意義了!分享是為了讓大家學到更多,收獲更多。希望我的這篇能夠給大家一點點收獲!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved