Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之ListView列表刷新和加載更多實現方法

Android開發之ListView列表刷新和加載更多實現方法

編輯:關於Android編程

本文實例講述了Android開發之ListView列表刷新和加載更多實現方法。分享給大家供大家參考。具體如下:

上下拉實現刷新和加載更多的ListView,如下:

package com.sin.android.ui; 
import android.content.Context; 
import android.util.AttributeSet; 
import android.view.Gravity; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.AbsListView; 
import android.widget.AbsListView.OnScrollListener; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
/** 
 * 動態刷新和加載數據ListView 
 * @author RobinTang 
 * 
 */ 
public class DynamicListView extends ListView implements OnScrollListener { 
  /** 
   * 監聽器 
   * 監聽控件的刷新或者加載更多事件 
   * 所有的條目事件都會有一個偏移量,也就是position應該減1才是你適配器中的條目 
   * @author RobinTang 
   * 
   */ 
  public interface DynamicListViewListener { 
    /** 
     * 
     * @param dynamicListView 
     * @param isRefresh 為true的時候代表的是刷新,為false的時候代表的是加載更多 
     * @return true:刷新或者加載更多動作完成,刷新或者加載更多的動畫自動消失 false:刷新或者加載更多為完成,需要在數據加載完成之後去調用控件的doneRefresh()或者doneMore()方法 
     */ 
    public boolean onRefreshOrMore(DynamicListView dynamicListView, boolean isRefresh); 
  } 
  /** 
   * 狀態控件(StatusView,列表頭上和底端的)的狀態枚舉 
   * @author RobinTang 
   * 
   */ 
  enum RefreshStatus { 
    none, normal, willrefresh, refreshing 
  } 
  /** 
   * 狀態控件 
   * @author RobinTang 
   * 
   */ 
  class StatusView extends LinearLayout { 
    public int height; 
    public int width; 
    private ProgressBar progressBar = null; 
    private TextView textView = null; 
    private RefreshStatus refreshStatus = RefreshStatus.none; 
    private String normalString = "下拉刷新"; 
    private String willrefreshString = "松開刷新"; 
    private String refreshingString = "正在刷新"; 
    public StatusView(Context context, AttributeSet attrs) { 
      super(context, attrs); 
      initThis(context); 
    } 
    public StatusView(Context context) { 
      super(context); 
      initThis(context); 
    } 
    private void initThis(Context context) { 
      this.setOrientation(LinearLayout.HORIZONTAL); 
      this.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); 
      progressBar = new ProgressBar(context); 
      progressBar.setLayoutParams(new LinearLayout.LayoutParams(30, 30)); 
      textView = new TextView(context); 
      textView.setPadding(5, 0, 0, 0); 
      this.addView(progressBar); 
      this.addView(textView); 
      int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 
      int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 
      this.measure(w, h); 
      height = this.getMeasuredHeight(); 
      width = this.getMeasuredWidth(); 
      this.setRefreshStatus(RefreshStatus.normal); 
    } 
    public RefreshStatus getRefreshStatus() { 
      return refreshStatus; 
    } 
    public void setRefreshStatus(RefreshStatus refreshStatus) { 
      if (this.refreshStatus != refreshStatus) { 
        this.refreshStatus = refreshStatus; 
        if(refreshStatus == RefreshStatus.refreshing){ 
          this.progressBar.setVisibility(View.VISIBLE); 
        } 
        else{ 
          this.progressBar.setVisibility(View.GONE); 
        } 
        refreshStatusString(); 
        this.invalidate(); 
      } 
    } 
    private void refreshStatusString() { 
      switch (refreshStatus) { 
      case normal: 
        textView.setText(normalString); 
        progressBar.setProgress(0); 
        break; 
      case willrefresh: 
        textView.setText(willrefreshString); 
        break; 
      case refreshing: 
        textView.setText(refreshingString); 
        break; 
      default: 
        break; 
      } 
    } 
    /** 
     * 設置狀態字符串 
     * @param normalString 平時的字符串 
     * @param willrefreshString 松開後刷新(或加載)的字符串 
     * @param refreshingString 正在刷新(或加載)的字符串 
     */ 
    public void setStatusStrings(String normalString, String willrefreshString, String refreshingString){ 
      this.normalString = normalString; 
      this.willrefreshString = willrefreshString; 
      this.refreshingString = refreshingString; 
      this.refreshStatusString(); 
    } 
  } 
  private StatusView refreshView; 
  private StatusView moreView; 
  private int itemFlag = -1; 
  private boolean isRecorded = false; 
  private int downY = -1; 
  private final float minTimesToRefresh = 1.5f; 
  private final static int ITEM_FLAG_FIRST = 1; 
  private final static int ITEM_FLAG_NONE = 0; 
  private final static int ITEM_FLAG_LAST = -1; 
  // 兩個監聽器 
  private DynamicListViewListener onRefreshListener; 
  private DynamicListViewListener onMoreListener; 
  // 滾動到低端的時候是否自動加載更多 
  private boolean doMoreWhenBottom = false; 
  public DynamicListView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    initThis(context); 
  } 
  public DynamicListView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initThis(context); 
  } 
  public DynamicListView(Context context) { 
    super(context); 
    initThis(context); 
  } 
  private void initThis(Context context) { 
    refreshView = new StatusView(context); 
    moreView = new StatusView(context); 
    refreshView.setStatusStrings("繼續下拉刷新數據...", "松開之後刷新數據...", "正在刷新數據..."); 
    moreView.setStatusStrings("繼續上拉加載數據...", "松開之後加載數據...", "正在加載數據..."); 
    this.addHeaderView(refreshView, null, false); 
    this.addFooterView(moreView, null, false); 
    this.setOnScrollListener(this); 
    doneRefresh(); 
    doneMore(); 
  } 
  // 監聽器操作 
  public DynamicListViewListener getOnRefreshListener() { 
    return onRefreshListener; 
  } 
  public void setOnRefreshListener(DynamicListViewListener onRefreshListener) { 
    this.onRefreshListener = onRefreshListener; 
  } 
  public DynamicListViewListener getOnMoreListener() { 
    return onMoreListener; 
  } 
  public void setOnMoreListener(DynamicListViewListener onMoreListener) { 
    this.onMoreListener = onMoreListener; 
  } 
  // 設置 
  public boolean isDoMoreWhenBottom() { 
    return doMoreWhenBottom; 
  } 
  public void setDoMoreWhenBottom(boolean doMoreWhenBottom) { 
    this.doMoreWhenBottom = doMoreWhenBottom; 
  } 
  @Override 
  public void onScroll(AbsListView l, int t, int oldl, int count) { 
    // log("%d %d %d", t, oldl, count); 
    if (t == 0) 
      itemFlag = ITEM_FLAG_FIRST; 
    else if ((t + oldl) == count){ 
      itemFlag = ITEM_FLAG_LAST; 
      if(doMoreWhenBottom && onMoreListener != null && moreView.getRefreshStatus() != RefreshStatus.refreshing){ 
          doMore(); 
      } 
    } 
    else { 
      itemFlag = ITEM_FLAG_NONE; 
//     isRecorded = false; 
    } 
  } 
  @Override 
  public void onScrollStateChanged(AbsListView arg0, int arg1) { 
  } 
  @Override 
  public boolean onTouchEvent(MotionEvent ev) { 
    switch (ev.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
      if (isRecorded == false && (itemFlag == ITEM_FLAG_FIRST && onRefreshListener != null && refreshView.getRefreshStatus() == RefreshStatus.normal || itemFlag == ITEM_FLAG_LAST && onMoreListener != null && moreView.getRefreshStatus() == RefreshStatus.normal)) { 
        downY = (int) ev.getY(0); 
        isRecorded = true; 
//       log("按下,記錄:%d flag:%d", downY, itemFlag); 
      } 
      break; 
    case MotionEvent.ACTION_UP: { 
      isRecorded = false; 
      if (onRefreshListener != null && refreshView.getRefreshStatus() == RefreshStatus.willrefresh) { 
        doRefresh(); 
      } else if (refreshView.getRefreshStatus() == RefreshStatus.normal) { 
        refreshView.setPadding(0, -1 * refreshView.height, 0, 0); 
      } 
      if (onMoreListener != null && moreView.getRefreshStatus() == RefreshStatus.willrefresh) { 
        doMore(); 
      } else if (moreView.getRefreshStatus() == RefreshStatus.normal) { 
        moreView.setPadding(0, 0, 0, -1 * moreView.height); 
      } 
      break; 
    } 
    case MotionEvent.ACTION_MOVE: { 
      if (isRecorded == false && (itemFlag == ITEM_FLAG_FIRST && onRefreshListener != null && refreshView.getRefreshStatus() == RefreshStatus.normal ||  
          itemFlag == ITEM_FLAG_LAST && onMoreListener != null && moreView.getRefreshStatus() == RefreshStatus.normal)) { 
        downY = (int) ev.getY(0); 
        isRecorded = true; 
//       log("按下,記錄:%d flag:%d", downY, itemFlag); 
      } else if (isRecorded) { 
        int nowY = (int) ev.getY(0); 
        int offset = nowY - downY; 
        if (offset > 0 && itemFlag == ITEM_FLAG_FIRST) { 
          // 下拉 
          setSelection(0); 
          if (offset >= (minTimesToRefresh * refreshView.height)) { 
            refreshView.setRefreshStatus(RefreshStatus.willrefresh); 
          } else { 
            refreshView.setRefreshStatus(RefreshStatus.normal); 
          } 
          refreshView.setPadding(0, -1 * (refreshView.height - offset), 0, 0); 
        } else if(itemFlag == ITEM_FLAG_LAST){ 
          // 上拉 
          setSelection(this.getCount()); 
          if (offset <= -1 * (minTimesToRefresh * moreView.height)) { 
            moreView.setRefreshStatus(RefreshStatus.willrefresh); 
          } else { 
            moreView.setRefreshStatus(RefreshStatus.normal);
          } 
          moreView.setPadding(0, 0, 0, -1 * (moreView.height + offset));
        } 
//       log("位移:%d", offset); 
      } 
      break; 
    } 
    default: 
      break; 
    } 
    return super.onTouchEvent(ev); 
  } 
  /** 
   * 開始刷新 
   */ 
  private void doRefresh(){ 
//   log("開始刷新"); 
    refreshView.setRefreshStatus(RefreshStatus.refreshing); 
    refreshView.setPadding(0, 0, 0, 0); 
    if(onRefreshListener.onRefreshOrMore(this, true)) 
      doneRefresh(); 
  } 
  /** 
   * 開始加載更多 
   */ 
  private void doMore(){ 
//   log("加載更多"); 
    moreView.setRefreshStatus(RefreshStatus.refreshing); 
    moreView.setPadding(0, 0, 0, 0); 
    if(onMoreListener.onRefreshOrMore(this, false)) 
      doneMore(); 
  } 
  /** 
   * 刷新完成之後調用,用於取消刷新的動畫 
   */ 
  public void doneRefresh() { 
//   log("刷新完成!"); 
    refreshView.setRefreshStatus(RefreshStatus.normal); 
    refreshView.setPadding(0, -1 * refreshView.height, 0, 0); 
  } 
  /** 
   * 加載更多完成之後調用,用於取消加載更多的動畫 
   */ 
  public void doneMore() { 
//   log("加載完成!"); 
    moreView.setRefreshStatus(RefreshStatus.normal); 
    moreView.setPadding(0, 0, 0, -1 * moreView.height); 
  } 
  /** 
   * 獲取刷新的狀態 
   * @return 一般 將要刷新 刷新完成 
   */ 
  public RefreshStatus getRefreshStatus(){ 
    return refreshView.getRefreshStatus(); 
  } 
  /** 
   * 獲取加載更多的狀態 
   * @return 一般 將要加載 加載完成 
   */ 
  public RefreshStatus getMoreStatus(){ 
    return moreView.getRefreshStatus(); 
  } 
// private void log(Object obj) { 
//   log("%s", obj.toString()); 
// } 
// 
// private void log(String format, Object... args) { 
//   Log.i("DynamicListView", String.format(format, args)); 
// } 
} 

使用例子:

package com.sin.android.ui; 
import java.util.ArrayList; 
import java.util.Date; 
import android.annotation.SuppressLint; 
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.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.Toast; 
import com.sin.android.ui.DynamicListView.DynamicListViewListener; 
@SuppressLint("HandlerLeak") 
public class MainActivity extends Activity implements DynamicListViewListener { 
  DynamicListView listView; 
  ArrayList<String> data; 
  ArrayAdapter<String> adapter; 
  // 用於刷新控件狀態 
  Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
      if (msg.what == 0) { 
        adapter.notifyDataSetChanged(); 
        listView.doneRefresh(); 
        Toast.makeText(MainActivity.this, "新加載"+msg.arg1+"條數據!", Toast.LENGTH_LONG).show(); 
      } else if (msg.what == 1) { 
        adapter.notifyDataSetChanged(); 
        listView.doneMore(); 
      } else { 
        super.handleMessage(msg); 
      } 
    } 
  }; 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    listView = new DynamicListView(this); 
    setContentView(listView); 
    data = new ArrayList<String>(); 
    for (int i = 1; i < 10; ++i) { 
      data.add("原始數據" + i); 
    } 
    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, data); 
    listView.setAdapter(adapter); 
    listView.setOnItemClickListener(new OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
        Log.i("",data.get(arg2-1)); 
      } 
    }); 
    listView.setDoMoreWhenBottom(false);  // 滾動到低端的時候不自己加載更多 
    listView.setOnRefreshListener(this); 
    listView.setOnMoreListener(this); 
  } 
  @Override 
  public boolean onRefreshOrMore(DynamicListView dynamicListView, boolean isRefresh) { 
    if (isRefresh) { 
      new Thread(new Runnable() { 
        @Override 
        public void run() { 
          // 刷新 
          ArrayList<String> temp = new ArrayList<String>(); 
          for (int i = 0; i < 3; ++i) { 
            temp.add(0, new Date().toLocaleString()); 
            try { 
              Thread.sleep(1000); 
            } catch (InterruptedException e) { 
              e.printStackTrace(); 
            } 
          } 
          synchronized (data) { 
            data.addAll(0, temp); 
          } 
          Message message = new Message(); 
          message.what = 0; 
          message.arg1 = temp.size(); 
          handler.sendMessage(message); 
        } 
      }).start(); 
    } else { 
      new Thread(new Runnable() { 
        @Override 
        public void run() { 
          // 加載更多 
          ArrayList<String> temp = new ArrayList<String>(); 
          for (int i = 0; i < 3; ++i) { 
            temp.add(new Date().toLocaleString()); 
            try { 
              Thread.sleep(1000); 
            } catch (InterruptedException e) { 
              e.printStackTrace(); 
            } 
          } 
          synchronized (data) { 
            data.addAll(temp); 
          } 
          handler.sendEmptyMessage(1); 
        } 
      }).start(); 
    } 
    return false; 
  } 
} 

運行截圖如下:

希望本文所述對大家的Android程序設計有所幫助。

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