最近项目中用到了弹性滑动,但是这个弹性滑动只有在2.3之后才有了功能函数,在2.2以及之前的版本中,只有自己去实现了。
查了一下网上的资源,貌似没有提供出来一个具体的方式来实现。看到一个牛人写的一个软件中实现了弹性滑动,查了查源码,然后看了看ListView的源码,然后自己搞了一下,实现了弹性滑动。
基本思路就是得到出当前的可显示的item的位置,然后判断出否是越界,这里的越界就是是否有过度的滑动。如果有的话,就利用ScrollTo()这个方法,先把控件滑动到手势触摸事件的位置,当触摸事件结束时,滑动到屏幕顶端,或者末端。
首先是自定义一个类,继承ListView,然后在其中加入手势的事件模型。在处理touch事件时将事件交给手势listener来处理。并且返回父类的处理结果。
实现过度滑动,item跟随手势的代码是这一段:
scrollTo(0, distance/2);使得item只是过度滑动你所滑动距离的一半,这样更美观。
而实现弹性滑动的基本思路就是滑动回去加个时间。
代码如下:
这个代码是从项目中摘出的。只有上面的弹性滑动,下边部分其实一样。
显示效果如下
[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的不一样。在研究中,哪位兄台如果知道其中原来,还请告知一声。
查了一下网上的资源,貌似没有提供出来一个具体的方式来实现。看到一个牛人写的一个软件中实现了弹性滑动,查了查源码,然后看了看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的不一样。在研究中,哪位兄台如果知道其中原来,还请告知一声。