【参考链接】
跟前面的拖动不一样
比如说有一个自定义ViewGroup,当手指在这个ViewGroup中移动的时候,能够滑动ViewGroup中的内容。
这里为了跟后面的连贯,主要介绍使用scrollTo()/scrollBy()来实现的方式。
此外,Android还定义了系统所能够识别出的被认为是滑动的最小距离。当手指在屏幕上滑动的时候,如果两次滑动之间的距离小于这个常量,那么系统就不认为是在进行滑动操作。可以使用ViewConfiguration类的getScaledTouchSlop()方法获取这个常量
如下代码自定义了一个ViewGroup继承自FrameLayout,当手指在其上滑动的时候能够滑动其中的内容
public class MyFrameLayout extends FrameLayout {
//内容的最大值、最小值
private int minX=0;
private int maxX=0;
//滑动坐标的最大值、最小值
private int minScrollX;
private int maxScrollX;
private int lastX;
public MyFrameLayout(Context context) {
super(context);
}
public MyFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//计算出内容的最大值最小值
for(int i=0; i<getChildCount(); i++){
View childView = getChildAt(i);
if(minX>childView.getLeft())
minX=childView.getLeft();
if(maxX<childView.getRight())
maxX=childView.getRight();
}
//计算出滑动坐标的最大值、最小值//只有内容大小超出自身大小时,才能进行滑动
if(minX<0)
minScrollX=minX;
else
minScrollX=0;
if(maxX>getWidth())
maxScrollX=maxX-getWidth();
else
maxScrollX=0;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
lastX=(int) event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
int newX= (int) event.getRawX();
int deltaX=newX-lastX;
if (Math.abs(deltaX)> ViewConfiguration.get(getContext()).getScaledTouchSlop()) {
int newScrollX = getScrollX() + (-deltaX); //delta值要取反,因为scroll()参数跟滑动坐标系相反
if (newScrollX > maxScrollX)
newScrollX = maxScrollX;
if (newScrollX < minScrollX)
newScrollX = minScrollX;
scrollTo(newScrollX, getScrollY());
//更新坐标
lastX = newX;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
lastX=(int) event.getRawX();
break;
default:
break;
}
return true;
}
}