CustomView的手势缩放总结
两种方法:
一,利用ScaleGestureDetector。代码在customview中。
设为View的成员变量;
构造方法中传入OnScaleGestureListener,覆写缩放的三个方法;
覆写customView的onTouchEven(MotionEvent event)方法,将event传给ScaleGestureDetector. onTouchEven(MotionEvent event)处理。
OnScaleGestureListener listener = new OnScaleGestureListener() {
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.i("OnScaleGestureListener", "onScaleEnd");
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.i("OnScaleGestureListener", "onScaleBegin");
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
Log.i("OnScaleGestureListener", "onScale");
float dXStart = detector.getPreviousSpanX();
float dXEnd = detector.getCurrentSpanX();
float dScale = (dXEnd - dXStart) / getWidth();
scale += dScale;
if(scale > 3f) {
scale = 3f;
}
if(scale < 1) {
scale = 1f;
}
// Log.i("xFirstStart,xSecondStart,xFirstEnd", xFirstStart + "," + xSecondStart + "," + xFirstEnd + "," + xSecondEnd);
// Log.i("dXStart,dXEnd,scale,kcvKchart.getWidth()", dXStart + "," + dXEnd + "," + scale + "," + kcvKchart.getWidth());
setScaleX(scale);
return false;
}
};
二,直接设置customView的onTouchEventListener,覆写onTouch()方法。代码在activity中。
这里注意,可以使用MotionEvent.ACTION_POINTER_DOWN事件,比较方便;
如果不使用pointerdown事件,则在down事件中不能获取第二个pointer信息,只能在move事件中获取,第一获取后不做处理,第二次获取后做缩放。
// 没有使用MotionEvent.ACTION_POINTER_DOWN事件
kcvKchart.setOnTouchListener(new OnTouchListener() {
private float xFirstStart;
private float xSecondStart;
private float xFirstEnd;
private float xSecondEnd;
private int dXFirst;
private int oldPointerCount;
private int newPointerCount;
private float scale = 1f;
@Override
public boolean onTouch(View v, MotionEvent event) {// can be written in KChartView‘s onTouchEven(--)
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
xFirstStart = event.getX();// to WindowScreen
oldPointerCount = event.getPointerCount();
break;
case MotionEvent.ACTION_MOVE:
newPointerCount = event.getPointerCount();
if(newPointerCount == 1) {// one finger translate
xFirstEnd = event.getX();
dXFirst = Math.round(xFirstStart - xFirstEnd);// the closest integer to the argument,including positive & negative .
// TODO condition:if left x axis < 0 || right x axis > view.getWidth, then left x=0 || right x=view.getWidth return
kcvKchart.scrollBy(dXFirst, 0); // can called repeatedly
// Log.i("startX - endX, distanceX", xFirstStart - xFirstEnd + "," + dXFirst);
xFirstStart = xFirstEnd;
} else {// two or more finger scale
xFirstEnd = event.getX();
xSecondEnd = event.getX(1);
if(oldPointerCount == 1) {// initialize second pointer axis
// 由于第二个pointer的初始坐标不能再down事件中获取,只能在第一次move时获取,故第一次move不能进行缩放,需要过滤
oldPointerCount = newPointerCount;
} else {
float dXStart = Math.abs(xFirstStart - xSecondStart);
float dXEnd = Math.abs(xFirstEnd - xSecondEnd);
float dScale = (dXEnd - dXStart) / kcvKchart.getWidth();
scale += dScale;
if(scale > 3f) {
scale = 3f;
}
if(scale < 1) {
scale = 1f;
}
// Log.i("xFirstStart,xSecondStart,xFirstEnd", xFirstStart + "," + xSecondStart + "," + xFirstEnd + "," + xSecondEnd);
// Log.i("dXStart,dXEnd,scale,kcvKchart.getWidth()", dXStart + "," + dXEnd + "," + scale + "," + kcvKchart.getWidth());
kcvKchart.setScaleX(scale);
}
xFirstStart = xFirstEnd;
xSecondStart = xSecondEnd;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
default:
break;
}
return true;
}
} );