当需要指定ListView具体显示的Item时,可以通过如下代码来实现:
mListView.setSelection(position);
但这个方法类似scrollTo,是瞬间完成的移动。除此之外,还可以使用如下代码来实现平滑移动。
mListView.smoothScrollToPosition(position);
mListView.smoothScrollByOffset(offset);
mListView.smoothScrollBy(distance, duration);
ListView滑动监听
ListView的滑动监听,是ListView中最重要的技巧,很多重写的ListView,基本上都是在滑动事件的处理上下功夫,通过判断滑动事件进行不同的逻辑处理。而为了更加精确地监听滑动事件,开发者通常还需要使用GestureDetector手势识别、VelocityTracker滑动速度检测等辅助类来完成更好的监听。一般有两种监听方式,一种是通过OnTouchListener来实现监听,另一种是使用OnScrollListener来实现监听。
OnTouchListener
通过ACTION_DOWN、ACTION_MOVE、ACTION_UP这三个事件发生时的坐标,就可以根据坐标判断用户滑动的方向,并在不同的事件中进行相应的逻辑处理,代码如下:
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://触摸时操作
break;
case MotionEvent.ACTION_MOVE://移动时操作
break;
case MotionEvent.ACTION_UP://离开时操作
break;
}
return false;
}
});
OnScrollListener
OnScrollListener是AbsListView中的监听事件,它封装了很多与ListView相关的信息,使用也更加灵活。
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
private int lastVisibleItemPosition;//上次第一个可视的Item的ID
/**
* 当用户没有做手指抛动的状态时,这个方法只会回调2次,否则会回调3次,差别就是手指抛动的这个状态。
* 通常情况下,我们会在这个方法中通过不同的状态来设置一些标志Flag,来区分不同的滑动状态,供其它
* 方法处理。
* @param view
* @param scrollState
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
//滑动停止时
Log.d("Test", "SCROLL_STATE_IDLE");
break;
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
//正在滚动
Log.d("Test", "SCROLL_STATE_TOUCH_SCROLL");
break;
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
//手指抛动时,即手指用力滑动,在离开后ListView由于惯性继续滑动的状态
Log.d("Test", "SCROLL_STATE_FLING");
break;
}
}
/**
* 该方法在ListView滚动时会一直回调,通过该方法的后3个参数,可以很方便地进行一些判断
* @param view
* @param firstVisibleItem 当前能看见的第一个Item的ID(从0开始)
* @param visibleItemCount 当前看见的Item总数(包括没有显示完整的Item)
* @param totalItemCount 整个ListView的Item总数
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//滚动时一直调用
Log.d("Test", "onScroll");
//判断是否滚动到最后一行
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
}
//判断滚动的方向
if (firstVisibleItem > lastVisibleItemPosition) {
//上滑
} else if (firstVisibleItem < lastVisibleItemPosition) {
//下滑
}
lastVisibleItemPosition = firstVisibleItem;
}
});
另外,ListView也给我们提供了一些封装的方法来获得当前可视的Item的位置信息:
//获取可视区域内最后一个Item的id
mListView.getLastVisiblePosition();
//获取可视区域内第一个Item的id
mListView.getFirstVisiblePosition();
具有弹性的ListView
我们在查看ListView的源代码时可以发现,ListView中有一个控制滑动到边缘的处理方法,如下所示:
protected boolean overScrollBy(int deltaX, int deltaY,
int scrollX, int scrollY,
int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY,
boolean isTouchEvent)
注意参数:maxOverScrollY,注释中写道——Number of pixels to overscroll by in either direction along the Y axis。由此可以发现,虽然它的默认值是0,但其实只要修改这个参数的值,就可以让ListView具有弹性了。代码如下:
package com.example.huangfei.myapplication;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.ListView;
/**
* Created by huangfeihong on 2016/5/4.
* 具有弹性的ListView
*/
public class FlexibleListView extends ListView {
private int mMaxOverDistance = 50;
private Context mContext;
public FlexibleListView(Context context) {
super(context);
mContext = context;
init();
}
public FlexibleListView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
public FlexibleListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init();
}
//让不同分辨率设备的弹性距离基本一致
private void init() {
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
float density = metrics.density;
mMaxOverDistance = (int) (density * mMaxOverDistance);
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxOverDistance, isTouchEvent);
}
}
参考与:http://blog.csdn.net/tw19911005/article/details/51308242