以下内容可以帮助您入门。不过,它确实需要一些工作,当我解决它时,我会更新它。此代码需要 Android 2.2 才能运行,但您可以通过将 ScaleGestureDetector 从 AOSP 中取出来使其在早期设备上运行。
public class FullGallery extends Gallery implements OnDoubleTapListener, OnGestureListener, OnScaleGestureListener {
static final int NONE = 0;
static final int DRAG = 1;
int mode = NONE;
String TAG = "Gallery";
private Context c;
private final LayoutInflater mInflater;
private ScaleGestureDetector mScaleDetector;
private GestureDetector mDetector;
private float mScaleFactor = 1.f;
float new_distance_touch, old_distance_touch, init_x, init_y;
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
PointF mid = new PointF();
PointF start = new PointF();
ImageView imgPicture;
public FullGallery(Context context, AttributeSet attrSet) {
super(context, attrSet);
mInflater = LayoutInflater.from(context);
c = context;
mDetector = new GestureDetector(c,this);
mScaleDetector = new ScaleGestureDetector(c, this);
}
private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){
return e2.getX() > e1.getX();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
imgPicture = (ImageView) super.getSelectedView();
if (mDetector.onTouchEvent(event)) {
Log.d("onTouchEvent", "--[ MOVEMENT ]--");
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
init_x = event.getX();
init_y = event.getY();
midPoint(mid, event);
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
}
break;
}
imgPicture = (ImageView) super.getSelectedView();
imgPicture.setImageMatrix(matrix);
return true;
}
else if(mScaleDetector.onTouchEvent(event)) { // scale detector for zoom
Log.d("onTouchEvent", "--[ SCALE ]--");
return true;
}
else
return false;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
if (new_distance_touch > 10f) {
matrix.set(savedMatrix);
matrix.postScale(mScaleFactor, mScaleFactor, mid.x, mid.y);
Log.d("ZOOMMING",matrix.toShortString());
}
else {
matrix.set(savedMatrix);
matrix.postTranslate(init_x - start.x, init_y - start.y);
Log.d("PANNING",matrix.toShortString());
}
imgPicture.setImageMatrix(matrix);
imgPicture.invalidate();
Log.d("MATRIX", matrix.toString());
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.d(TAG, "-- onScaleBegin --");
matrix = imgPicture.getImageMatrix();
savedMatrix.set(matrix);
start.set(init_x, init_y);
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.d(TAG, "-- onScaleEnd --");
old_distance_touch = detector.getPreviousSpan();
new_distance_touch = detector.getCurrentSpan();
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(TAG, "-- onFling --");
float velMax = 2500f;
float velMin = 1000f;
float velX = Math.abs(velocityX);
if (velX > velMax) {
velX = velMax;
} else if (velX < velMin) {
velX = velMin;
}
velX -= 600;
int k = 500000;
int speed = (int) Math.floor(1f / velX * k);
setAnimationDuration(speed);
int kEvent;
if (isScrollingLeft(e1, e2)) {
kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
} else {
kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
}
onKeyDown(kEvent, null);
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.d(TAG, "-- onScroll --");
return super.onScroll(e1, e2, distanceX, distanceY);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
@Override
public void onGesture(GestureOverlayView overlay, MotionEvent event) {
// TODO Auto-generated method stub
}
@Override
public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
// TODO Auto-generated method stub
}
@Override
public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
// TODO Auto-generated method stub
}
@Override
public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
// TODO Auto-generated method stub
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}