Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之ListView分頁加載數據功能實現代碼

Android之ListView分頁加載數據功能實現代碼

編輯:關於Android編程

什麼是ListView分頁加載數據功能呢?在現在的大數據時代,我們不可能把某些數據全部展示到界面,好比我們經常會看的QQ空間一樣,當你看動態的時候,系統不可能會把所有好友的動態都展示在上面,你能看到的一般都是最新好友更新的動態,假如你要看非最新的好友動態,通常你都會手指向上滑動屏幕然後去查看,當界面下滑到一定數量的時候,就會看到一個“查看更多”,然後突然停頓一下,系統會通過網絡去給你刷新其他動態信息,這樣的功能我們一般叫做數據下拉刷新功能,也就是我們的分頁加載功能,具體的實現是怎樣的呢?下面我們開始詳細講解。

實現的原理:
1. 首先要先確定默認展示在ListView上的數據,比如默認在ListView上展示10條數據。
2. 將數據傳遞到自定義的適配器上,然後加載到ListView中。
3. 當用戶將數據拉到最後一條的時候,就要開始刷新加載新數據了。
4. 通過監聽ListView的滑動事件,判斷是否達到最後一條,如果達到最後一條則開始刷新。

詳細的實現步奏在代碼中詳細講解。

整體結構如下:

這裡寫圖片描述

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.company.listviewdeepknow.MainActivity">

  <ListView
    android:id="@+id/mList"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  </ListView>
</RelativeLayout>

foot_boot.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="70dp"
  android:gravity="center"
  android:orientation="horizontal">

  <ProgressBar
    android:id="@+id/progressBar"
    
    android:layout_width="45dp"
    android:layout_height="45dp" />

  <TextView
    android:id="@+id/mLoad"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="加載更多..."
    android:textSize="20sp" />
</LinearLayout>

list_item.xml

<?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="match_parent"
  android:orientation="horizontal">

  <TextView
    android:id="@+id/mTv1"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:textSize="20sp" />

  <TextView
    android:id="@+id/mTv2"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_alignParentRight="true"
    android:textSize="20sp" />
</RelativeLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyOnScrollListener.OnloadDataListener {
  //ListView展示的數據項
  private List<Student> data;
  //ListView控件
  private ListView mList;

  //自定義適配器
  MyAdapter adapter;

  //底部加載更多布局
  View footer;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //首先加載默認數據,這裡設置為10條
    getData();
    //顯示到ListView上
    showListView(data);
    //自定義的滾動監聽事件
    MyOnScrollListener onScrollListener = new MyOnScrollListener(footer, data);
    //設置接口回調
    onScrollListener.setOnLoadDataListener(this);
    //設置ListView的滾動監聽事件
    mList.setOnScrollListener(onScrollListener);
  }

  /**
   * 初始化ListView數據,默認設置為10條
   */
  private void getData() {
    data = new ArrayList<>();
    Student stu = null;
    for (int i = 0; i < 10; i++) {
      stu = new Student();
      stu.setName("姓名" + i);
      stu.setSex(i % 2 == 0 ? "男" : "女");
      data.add(stu);
    }
  }

  /**
   * 將數據加載到ListView上
   *
   * @param data
   */
  private void showListView(List<Student> data) {
    //首先判斷適配器是否為空,首次運行肯定是為空的
    if (adapter == null) {
      //查到ListView控件
      mList = (ListView) findViewById(R.id.mList);
      //將底部加載一個加載更多的布局
      footer = LayoutInflater.from(this).inflate(R.layout.foot_boot, null);
      //初始狀態為隱藏
      footer.setVisibility(View.GONE);
      //加入到ListView的底部
      mList.addFooterView(footer);
      //創建adpter數據
      adapter = new MyAdapter(data);
      //設置adapter
      mList.setAdapter(adapter);
    } else {
      //不為空,則刷新數據
      this.data = data;
      //提醒ListView重新更新數據
      adapter.notifyDataSetChanged();
    }
  }


  @Override
  public void onLoadData(List<Student> data) {
    //加載數據完成後,展示數據到ListView
    showListView(data);
  }
}

MyOnScrollListener.java

public class MyOnScrollListener implements AbsListView.OnScrollListener {

  //ListView總共顯示多少條
  private int totalItemCount;

  //ListView最後的item項
  private int lastItem;

  //用於判斷當前是否在加載
  private boolean isLoading;

  //底部加載更多布局
  private View footer;

  //接口回調的實例
  private OnloadDataListener listener;

  //數據
  private List<Student> data;

  public MyOnScrollListener(View footer, List<Student> data) {
    this.footer = footer;
    this.data = data;
  }
  //設置接口回調的實例
  public void setOnLoadDataListener(OnloadDataListener listener) {
    this.listener = listener;
  }

  /**
   * 滑動狀態變化
   *
   * @param view
   * @param scrollState 1 SCROLL_STATE_TOUCH_SCROLL是拖動  2 SCROLL_STATE_FLING是慣性滑動 0SCROLL_STATE_IDLE是停止 , 只有當在不同狀態間切換的時候才會執行
   */
  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {
    //如果數據沒有加載,並且滑動狀態是停止的,而且到達了最後一個item項
    if (!isLoading && lastItem == totalItemCount && scrollState == SCROLL_STATE_IDLE) {
      //顯示加載更多
      footer.setVisibility(View.VISIBLE);
      Handler handler = new Handler();
      //模擬一個延遲兩秒的刷新功能
      handler.postDelayed(new Runnable() {
        @Override
        public void run() {
          if (listener != null) {
            //開始加載更多數據
            loadMoreData();
            //回調設置ListView的數據
            listener.onLoadData(data);
            //加載完成後操作什麼
            loadComplete();
          }
        }
      }, 2000);
    }
  }

  /**
   * 當加載數據完成後,設置加載標志為false表示沒有加載數據了
   * 並且設置底部加載更多為隱藏
   */
  private void loadComplete() {
    isLoading = false;
    footer.setVisibility(View.GONE);

  }

  /**
   * 開始加載更多新數據,這裡每次只更新三條數據
   */
  private void loadMoreData() {
    isLoading = true;
    Student stu = null;
    for (int i = 0; i < 3; i++) {
      stu = new Student();
      stu.setName("新名字" + i);
      stu.setSex("新性別" + i);
      data.add(stu);
    }
  }


  /**
   * 監聽可見界面的情況
   *
   * @param view       ListView
   * @param firstVisibleItem 第一個可見的 item 的索引
   * @param visibleItemCount 可以顯示的 item的條數
   * @param totalItemCount  總共有多少個 item
   */
  @Override
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    //當可見界面的第一個item + 當前界面多有可見的界面個數就可以得到最後一個item項了
    lastItem = firstVisibleItem + visibleItemCount;
    //總listView的item個數
    this.totalItemCount = totalItemCount;
  }
  //回調接口
  public interface OnloadDataListener {
    void onLoadData(List<Student> data);
  }
}

MyAdapter.java

public class MyAdapter extends MyBaseAdapter<Student> {

  public MyAdapter(List<Student> data) {
    super(data);
  }

  @Override
  public void setData(ViewHolder holder, Student t) {
    holder.setText(R.id.mTv1, t.getName()).setText(R.id.mTv2, t.getSex());

  }

}

MyBaseAdapter.java

public abstract class MyBaseAdapter<T> extends BaseAdapter {
  protected List<T> data;
  public MyBaseAdapter(List<T> data){
    this.data = data;
  }
  @Override
  public int getCount() {
    return data == null ? 0 : data.size();
  }

  @Override
  public Object getItem(int position) {
    return data.get(position);
  }

  @Override
  public long getItemId(int position) {
    return position;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = ViewHolder.getHolder(convertView,parent,position, R.layout.list_item);
    setData(holder,data.get(position));
    return holder.getConvertView();
  }
  public abstract void setData(ViewHolder holder,T t);
}

ViewHolder.java

public class ViewHolder {
  private int position;
  private SparseArray<View> array;
  private View convertView;
  private Context context;

  private ViewHolder(ViewGroup parent, int position, int layout) {
    this.position = position;
    this.context = parent.getContext();
    convertView = LayoutInflater.from(parent.getContext()).inflate(layout, null);
    convertView.setTag(this);
    array = new SparseArray<>();
  }

  public static ViewHolder getHolder(View convertView, ViewGroup parent, int position, int layout) {
    if (convertView == null) {
      return new ViewHolder(parent, position, layout);
    } else {
      ViewHolder holder = (ViewHolder) convertView.getTag();
      holder.position = position;
      return holder;
    }
  }

  public <T extends View> T getView(int viewId) {
    View view = array.get(viewId);
    if (view == null) {
      view = convertView.findViewById(viewId);
      array.put(viewId, view);
    }
    return (T) view;
  }

  public View getConvertView() {
    return convertView;
  }

  public ViewHolder setText(int viewId, String data) {
    TextView tv = getView(viewId);
    tv.setText(data);
    return this;
  }

 Student.java

public class Student {
  private String name;
  private String sex;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSex() {
    return sex;
  }

  public void setSex(String sex) {
    this.sex = sex;
  }
}

除了MyAdapter.java MyBaseAdapter.java ViewHolder.java 以及 Student.java實體類沒有注解,其他兩個主要實現類都已經注釋了,關於自定義通用適配器的講解,本篇不做講解,如果想了解如何實現自定義通用適配器知識的可以查看: 

下面可以看看效果圖:

這裡寫圖片描述

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

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