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) 方法。有待考证。