关于ListView的弹性滑动

最近项目中用到了弹性滑动,但是这个弹性滑动只有在2.3之后才有了功能函数,在2.2以及之前的版本中,只有自己去实现了。
查了一下网上的资源,貌似没有提供出来一个具体的方式来实现。看到一个牛人写的一个软件中实现了弹性滑动,查了查源码,然后看了看ListView的源码,然后自己搞了一下,实现了弹性滑动。
基本思路就是得到出当前的可显示的item的位置,然后判断出否是越界,这里的越界就是是否有过度的滑动。如果有的话,就利用ScrollTo()这个方法,先把控件滑动到手势触摸事件的位置,当触摸事件结束时,滑动到屏幕顶端,或者末端。
首先是自定义一个类,继承ListView,然后在其中加入手势的事件模型。在处理touch事件时将事件交给手势listener来处理。并且返回父类的处理结果。
public class BouncyListView extends ListView {

private Context context;
/*
* Slide over so that cross-border
*/
private boolean outBound = false;
private int distance;
private int firstOut;

public BouncyListView(Context context) {
super(context);
this.context = context;
}

public BouncyListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}

public BouncyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}

GestureDetector mGestureDetector = new GestureDetector(context,
new GestureDetector.OnGestureListener() {

@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}

@Override
public void onShowPress(MotionEvent e) {

}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
int firstPos = getFirstVisiblePosition();
int lastPos = getLastVisiblePosition();
int itemCount = getCount();
//outbound Top
if (outBound && firstPos != 0 && lastPos != (itemCount - 1)) {
scrollTo(0, 0);
return false;
}
View firstView = getChildAt(firstPos);
if (!outBound)
firstOut = (int) e2.getRawY();
if (firstView != null
&& (outBound || (firstPos == 0
&& firstView.getTop() == 0 && distanceY < 0))) {
//Record the length of each slide
distance = firstOut - (int) e2.getRawY();
scrollTo(0, distance/2);
return true;
}
//outbound Bottom


return false;
}

@Override
public void onLongPress(MotionEvent e) {

}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
return false;
}

@Override
public boolean onDown(MotionEvent e) {
return false;
}
});

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

int act = event.getAction();
if ((act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_CANCEL)
&& outBound) {
outBound = false;
//scroll back
}
if (!mGestureDetector.onTouchEvent(event)) {
outBound = false;
} else {
outBound = true;
}
return super.dispatchTouchEvent(event);
}

}


实现过度滑动,item跟随手势的代码是这一段:
int firstPos = getFirstVisiblePosition();
int lastPos = getLastVisiblePosition();
int itemCount = getCount();

if (outBound && firstPos != 0
&& lastPos != (itemCount - 1)) {
scrollTo(0, 0);
return false;
}
View firstView = getChildAt(firstPos);

if (!outBound)
firstOut = (int) e2.getRawY();
if (firstView != null && (outBound ||
(firstPos == 0 && firstView.getTop() == 0 && distanceY < 0))){

distance = firstOut - (int) e2.getRawY();
scrollTo(0, distance/2);
return true;
}


scrollTo(0, distance/2);使得item只是过度滑动你所滑动距离的一半,这样更美观。

而实现弹性滑动的基本思路就是滑动回去加个时间。
代码如下:
Rect rect = new Rect();
getLocalVisibleRect(rect);
TranslateAnimation am = new TranslateAnimation( 0, 0, -rect.top, 0);
am.setDuration(300);
startAnimation(am);
scrollTo(0, 0);

这个代码是从项目中摘出的。只有上面的弹性滑动,下边部分其实一样。
显示效果如下
[img]http://dl.iteye.com/upload/attachment/485988/223f76de-2fcf-368a-8cf9-467b8b92b592.png[/img]

看别人的代码往往会给自己带来一些思路,然后自己去研究,以上的思路可以应用与Gridview,我这里实现Gridview的弹性滑动是没有问题的。我目前遇到的一个问题就是ScrollView的弹性滑动问题。看了很长时间的ScrollView的源码,但是没有太好的思路,主要是在显示部分的坐标拿不到,不像ListView里可以通过getFirstVisiblePosition()这样一个方法来拿到item的位置,继而拿到item,ScrollView中只有一个子控件。他的滑动实现貌似跟ListView,Gridview这些采用Adapter的不一样。在研究中,哪位兄台如果知道其中原来,还请告知一声。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值