ListView繼承自AbsListView AbsListView中有一個滾動事件的Listenter,以下: public interface OnScrollListener {
/** * The view is not scrolling. Note navigating the list using the trackball counts as * being in the idle state since these transitions are not animated. */ public static int SCROLL_STATE_IDLE = 0;
/** * The user is scrolling using touch, and their finger is still on the screen */ public static int SCROLL_STATE_TOUCH_SCROLL = 1;
/** * The user had previously been scrolling using touch and had performed a fling. The * animation is now coasting to a stop */ public static int SCROLL_STATE_FLING = 2;
/** * Callback method to be invoked while the list view or grid view is being scrolled. If the * view is being scrolled, this method will be called before the next frame of the scroll is * rendered. In particular, it will be called before any calls to * {@link Adapter#getView(int, View, ViewGroup)}. * * @param view The view whose scroll state is being reported * * @param scrollState The current scroll state. One of {@link #SCROLL_STATE_IDLE}, * {@link #SCROLL_STATE_TOUCH_SCROLL} or {@link #SCROLL_STATE_IDLE}. */ public void onScrollStateChanged(AbsListView view, int scrollState);
/** * Callback method to be invoked when the list or grid has been scrolled. This will be * called after the scroll has completed * @param view The view whose scroll state is being reported * @param firstVisibleItem the index of the first visible cell (ignore if * visibleItemCount == 0) * @param visibleItemCount the number of visible cells * @param totalItemCount the number of items in the list adaptor */ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount); }
**************************************************************************************************************************************** private boolean mBusy=false; //滾動中 private OnScrollListener mOnScrollListener = new OnScrollListener(){ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case OnScrollListener.SCROLL_STATE_IDLE: mBusy = false; break; case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: mBusy = true; break; case OnScrollListener.SCROLL_STATE_FLING: mBusy = true; break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub } }; **************************************************** OnScrollListener還能夠方便的實現動態加載數據。 遇到問題要多思考。多動腦,少動手~~!
import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.widget.AbsListView;import android.widget.ArrayAdapter;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.AbsListView.OnScrollListener;public class ListViewActivity extends Activity { private ListView lv; private List<String> list; private int lastItem; private int listSize; private ListAdapter adapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView) findViewById(R.id.lv); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getData()); lv.setAdapter(adapter); lv.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView paramAbsListView, int paramInt) { //當屏幕中止滾動時爲0;當屏幕滾動且用戶使用的觸碰或手指還在屏幕上時爲1; //因爲用戶的操做,屏幕產生慣性滑動時爲2 System.out.println("***lastItem:"+lastItem); System.out.println("***listSize:"+listSize); if(lastItem == listSize){ System.out.println("**************"); //數據所有顯示出來時運行此處代碼,若是要實現分頁功能,在這裏加載下一頁的數據 } } @Override public void onScroll(AbsListView paramAbsListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {// // firstVisibleItem表示在現時屏幕第一個ListItem(部分顯示的ListItem也算)// // 在整個ListView的位置(下標從0開始) // System.out.println("***firstParamInt:"+firstVisibleItem);// // visibleItemCount表示在現時屏幕能夠見到的ListItem(部分顯示的ListItem也算)總數// System.out.println("***visibleItemCount:"+visibleItemCount);// // totalItemCount表示ListView的ListItem總數// System.out.println("***totalItemCount:"+totalItemCount); // listView.getLastVisiblePosition()表示在現時屏幕最後一個ListItem(最後ListItem要徹底 // 顯示出來纔算)在整個ListView的位置(下標從0開始)// System.out.println("****"+String.valueOf(lv.getLastVisiblePosition())); lastItem = lv.getLastVisiblePosition(); } }); } private List<String> getData(){ int i; list = new ArrayList<String>(); for(i=1; i<10; i++){ list.add("ListView"+i); } listSize = list.size()-1; return list; }} 若是還有什麼不懂的,見意去看下源碼。
[url=]回答[/url][url=]1[/url] 爲了得到這一行爲向下是棘手的,我花了至關長一段時間來完善。肉的問題是,本身的滾動聽衆是否是真的很足以探測到一個「滾動中止」(包括方向鍵/軌跡球),至於我能夠告訴。我結束了做品的權利,我但願它作的事情結合。 我想我能作到這一點的最好辦法是延長ListView和覆蓋的幾種方法: .... @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) { startWait(); } return super.onKeyUp(keyCode, event); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { stopWait(); } if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { startWait(); } return super.onTouchEvent(event); } private OnScrollListener customScrollListener = new OnScrollListener() { @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { stopWait(); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState =其餘= OnScrollListener.SCROLL_STATE_IDLE){startWait();} {stopWait();}}} / /全部這個等待可能獲得改善,可是這想法私人主題waitThread = NULL;私人詮釋waitCount = Integer.MIN_VALUE的;公共無效stopWait(){waitCount = Integer.MIN_VALUE的;}市民同步無效startWait(){waitCount = 0;(waitThread = NULL){;} waitThread =新主題(新的Runnable(){@覆蓋公共無效的run() {嘗試{(; waitCount.get()<10; waitCount + +){Thread.sleep代碼(50);} / /踢它返回到UI線程view.post(theRunnableWithYourOnScrollStopCode); / /這裏是你辦什麼你想要作關於中止}遇上(InterruptedException E){} {waitThread = NULL;}}}); waitThread.start();}請注意,您還能夠customScrollListener customScrollListener在你的構造。這種實現是不錯的,我以爲,由於它不會當即火「事件」,它會稍等一會,直到它實際上已經徹底中止滾動。
[url=]2[/url] 在年末,我已經達到了一個解決方案,沒有那麼多優雅的,但爲我工做;想通了,onScroll方法是所謂的每一步的滾動,而不是僅僅在滾動結束,和,onScrollStateChanged其實是被稱爲只有當滾動完成後,我這樣作: public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.currentFirstVisibleItem = firstVisibleItem; this.currentVisibleItemCount = visibleItemCount; } public void onScrollStateChanged(AbsListView view, int scrollState) { this.currentScrollState = scrollState; this.isScrollCompleted(); } private void isScrollCompleted() { if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) { /*** In this way I detect if there's been a scroll which has completed ***/ /*** do the work! ***/ } } *** / public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.currentFirstVisibleItem = firstVisibleItem; this.currentVisibleItemCount = visibleItemCount; } public void onScrollStateChanged(AbsListView view, int scrollState) { this.currentScrollState = scrollState; this.isScrollCompleted(); } private void isScrollCompleted() { if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) { /*** In this way I detect if there's been a scroll which has completed ***/ /*** do the work! ***/ } }實際上,每次的ListView的滾動我保存了有關的第一個可見的項目數據,並在可見的項目數(onScroll方法);時,滾動變化的狀態(onScrollStateChanged)我保存的狀態和我調用另外一個方法,這其實是瞭解是否有一個滾動的,若是它的完成。這樣,我也有可見項目,我須要的數據。也許不乾淨,但做品! 關於
若是adapter中的數據量很大的時候,在加載listview時會出現卡頓的現象。這是會讓用戶抓狂!最好的解決辦法就是先加載必定數量的數據,而後在最下方提示正在加載! 動態加載就是把放入adapter中的數據分好幾回加載。在用戶拖動listview時再加載必定的數據,和sina微博的客戶端相似。 給listview添加OnScrollListener監聽事件默認會覆蓋下面兩個方法: Java代碼 收藏代碼 OnScrollListener loadListener=new OnScrollListener() { @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { lastItem = firstVisibleItem + visibleItemCount; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //listview滾動時會執行這個方法,這兒調用加載數據的方法。 adapter.notifyDataSetChanged();//提醒adapter更新 uList.setSelection(lastItem - 1);//設置listview的當前位置,若是不設置每次加載完後都會返回到list的第一項。 } } }; TIP: 一、若是activity中只有listview,當listview的數據量很大時,在啓動activity時會卡頓半天知道數據加載完能夠顯示,這時能夠能夠用handler,將加載數據的操做寫在handler裏面,並且要在onResume()方法中執行,放在onCreate()不起做用。 二、若是是從網絡獲取數據,或者數據量很大能夠新開一個線程,在線程中完成數據的加載。 三、若是添加的加載提示框出不來,多是加載過程一直佔有cpu,沒法顯示提示框,能夠將加載的代碼寫到handler裏面,用postDelayed()方法給必定的時間延遲去加載數據。
在模擬器上,若是使用鼠標的滾輪來滾動時執行 onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 方法,不執行 onScrollStateChanged(AbsListView view, int scrollState) 方法。只有觸摸往下滑動時,才執行onScrollStateChanged(AbsListView view, int scrollState) 方法。有待考證。