展会信息港展会大全

ListView OnScrollListener详解(滑屏分页显示数据)
来源:互联网   发布日期:2015-11-26 10:23:37   浏览:5369次  

导读:SCROLL_STATE_FLING是指手指快速拖动后,手指离开,页面惯性滑动的状态。ListView之滚动事件--OnScrollListener在 onScrollStateChanged ( AbsListView view, int scrollState) 中,scrollState有三种状态......

SCROLL_STATE_FLING是指手指快速拖动后,手指离开,页面惯性滑动的状态。

ListView之滚动事件--OnScrollListener

在 onScrollStateChanged ( AbsListViewview, int scrollState) 中,scrollState有三种状态,分别是开始滚动( SCROLL_STATE_FLING ),正在滚动( SCROLL_STATE_TOUCH_SCROLL ), 已经停止( SCROLL_STATE_IDLE ),对于滚动事件的处理,很有必要知道。

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. */@Overridepublic 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() {@Overridepublic void onScrollStateChanged(AbsListView paramAbsListView, int paramInt) {//当屏幕停止滚动时为0;当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1;//由于用户的操作,屏幕产生惯性滑动时为2System.out.println("***lastItem:"+lastItem);System.out.println("***listSize:"+listSize);if(lastItem == listSize){System.out.println("**************");//数据全部显示出来时运行此处代码,如果要实现分页功能,在这里加载下一页的数据}}@Overridepublic 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;}} 如果还有什么不懂的,见意去看下源码。

OnScrollListener回调分析

如果adapter中的数据量很大的时候,在加载listview时会出现卡顿的现象。这是会让用户抓狂!最好的解决办法就是先加载一定数量的数据,然后在最下方提示正在加载!

动态加载就是把放入adapter中的数据分好几次加载。在用户拖动listview时再加载一定的数据,和sina微博的客户端类似。

给listview添加OnScrollListener监听事件默认会覆盖下面两个方法:

Java代码

1.new OnScrollListener() {

2.boolean isLastRow = false;

3.

4.@Override

5.public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

6.//滚动时一直回调,直到停止滚动时才停止回调。单击时回调一次。

7.//firstVisibleItem:当前能看见的第一个列表项ID(从0开始)

8.//visibleItemCount:当前能看见的列表项个数(小半个也算)

9.//totalItemCount:列表项共数

10.

11.//判断是否滚到最后一行

12.if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {

13.isLastRow = true;

14.}

15.}

16.@Override

17.public void onScrollStateChanged(AbsListView view, int scrollState) {

18.//正在滚动时回调,回调2-3次,手指没抛则回调2次。scrollState = 2的这次不回调

19.//回调顺序如下

20.//第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滚动

21.//第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的动作(手指离开屏幕前,用力滑了一下)

22.//第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滚动

23.

24.//当滚到最后一行且停止滚动时,执行加载

25.if (isLastRow && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {

26.//加载元素

27.......

28.

29.isLastRow = false;

30.}

31.}

32.}

一片国外的翻译文档,但是不是很正确

[url=]onScrollListener实施检测在ListView滚动年底[/url]

我ListView ListView显示一些项目。我想执行一些当前显示中的可见部分的项目ListView ListView,如何ListView中一直滚动,因此我认为OnScrollListener ListView ListView的。因此到Android API参考,onScroll法 将被称为滚动后已经完成 。这在我看来,我需要的东西,因为一旦滚动完成后,我在执行我的行动ListView (onScroll方法返回显示的第一项指数和显示的项目数)。

但 是,一旦实施,我看到LogCat LogCat onScroll方法,不只是发射一次滚动已完成,但发射进入显示视图为每一个新项目,从开始到结束滚动。这不是我所期望的行为,也没有我需要的。 ,而不是其他的侦听器的方法(onScrollStateChanged)不提供有关在当前显示的项目的ListView ListView 。

所以,没有人知道如何使用这两个方法来检测滚动的结束,并得到所显示的项目信息?之间的API参考资料和实际行为的方法不对,弄得我有点。预先感谢。

PS:我已经看到了一些类似的主题周围,但没有帮助我了解整个事情的作品..!

[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:

1、如果activity中只有listview,当listview的数据量很大时,在启动activity时会卡顿半天知道数据加载完可以显示,这 时可以可以用handler,将加载数据的操作写在handler里面,而且要在onResume()方法中执行,放在onCreate()不起作用。

2、如果是从网络获取数据,或者数据量很大可以新开一个线程,在线程中完成数据的加载。

3、如果添加的加载提示框出不来,可能是加载过程一直占有cpu,无法显示提示框,可以将加载的代码写到handler里面,用postDelayed()方法给一定的时间延迟去加载数据。

监听ListView滚动到最底部

监听ListView的滚动可以用两个东西:

ListView.onScrollStateChanged (本文讲解这个listener的使用)

在OnGestureListener类里面的onScroll(MotionEvent e1, MotionEvent e2,

float distanceX, float distanceY)事件

SDK的Sample里面的ApiDemos里面的List9 和 List 13介绍了 ListView.OnScrollListener的使用。

List9 介绍的是ListView.OnScrollListener的 onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 方法。

List13介绍的是ListView.OnScrollListener的 onScrollStateChanged(AbsListView view, int scrollState) 方法,使用说明如下:

ListView.setOnScrollListener(new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, intscrollState) {switch (scrollState) {case OnScrollListener.SCROLL_STATE_IDLE:Log.v("已经停止:SCROLL_STATE_IDLE");break;case OnScrollListener.SCROLL_STATE_FLING:Log.v("开始滚动:SCROLL_STATE_FLING");break;case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:Log.v("正在滚动:SCROLL_STATE_TOUCH_SCROLL");break;}}@Overridepublic void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount, int totalItemCount) {}});

监听ListView滚动到最底部使用 onScrollStateChanged(AbsListView view, int scrollState) 方法,代码大致如下:

// 监听listview滚到最底部mIndexList.setOnScrollListener(new OnScrollListener() {@Overridepublic voidonScrollStateChanged(AbsListView view, int scrollState) {switch (scrollState) {// 当不滚动时caseOnScrollListener.SCROLL_STATE_IDLE:// 判断滚动到底部if (view.getLastVisiblePosition() == (view.getCount() - 1)) {isLastisNext++;}break;}}@Overridepublic voidonScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {}});

我使用这个发现两个问题:

在模拟器上,如果使用鼠标的滚轮来滚动时执行 onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)方法,不执行 onScrollStateChanged(AbsListView view, int scrollState)方法。只有触摸往下滑动时,才执行onScrollStateChanged(AbsListView view, int scrollState) 方法。有待考证。

SCROLL_STATE_TOUCH_SCROLL一定执行,然后下面可能执行SCROLL_STATE_FLING,也可能执行SCROLL_STATE_IDLE。这个是不确定的。有待考证。

赞助本站

人工智能实验室

相关热词: OnScrollListener 分页

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港