Android双指缩放与拖动控件实现

双指缩放和移动控件在 Android 里其实不算难搞,核心就在两个手势检测器上:ScaleGestureDetectorGestureDetector。一个负责识别缩放,另一个搞定拖动,两者搭配一下,体验就上来了。你要是做图片查看器、地图缩放那种,真的挺好用。

ScaleGestureDetector 的用法挺简单,你只要监听onScale,拿到scaleFactor,改控件的setScaleXsetScaleY就完事:

ScaleGestureDetector scaleDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
  @Override
  public boolean onScale(ScaleGestureDetector detector) {
    float scaleFactor = detector.getScaleFactor();
    view.setScaleX(scaleFactor);
    view.setScaleY(scaleFactor);
    return true;
  }
});

别忘了在onTouchEvent里把event传进去:

@Override
public boolean onTouchEvent(MotionEvent event) {
  scaleDetector.onTouchEvent(event);
  return true;
}

GestureDetector用来拖动,思路类似,你监听onScroll就行:

GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
  @Override
  public boolean onDown(MotionEvent e) {
    return true;
  }
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    view.setTranslationX(view.getX() + distanceX);
    view.setTranslationY(view.getY() + distanceY);
    return true;
  }
});

,这个也要在onTouchEvent里一下:

@Override
public boolean onTouchEvent(MotionEvent event) {
  return gestureDetector.onTouchEvent(event);
}

控件回正这一块也别落下,有时候缩放拖动完,你控件弹回去。你可以在onScaleBegin记录下初始值,在onScaleEnd里恢复:

private float initialScale = 1.0f;
private float initialX, initialY;

@Override public void onScaleBegin(ScaleGestureDetector detector) { initialScale = view.getScaleX(); initialX = view.getX(); initialY = view.getY(); }

@Override public void onScaleEnd(ScaleGestureDetector detector) { view.setScaleX(initialScale); view.setScaleY(initialScale); view.setTranslationX(initialX); view.setTranslationY(initialY); }

嗯,如果你打算做手势交互,尤其是涉及多点触控的场景,这一套逻辑还挺值得上手试试。注意一下手势冲突、边界限制这些细节,体验能好不少。

你可以顺带看看下面这些相关文章:

rar 文件大小:5.2KB