支持单指滑动双指缩放的ImageView
import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
public class ZoomImageView extends android.support.v7.widget.AppCompatImageView {
private static final String TAG = "ZoomImageView";
private double lastD;
private Point lastCenter;
private int pCont;
public ZoomImageView(Context context) {
super(context);
setClickable(true);
}
public ZoomImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setClickable(true);
}
public ZoomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setClickable(true);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
pCont = 1;
return true;
case MotionEvent.ACTION_POINTER_DOWN:
pCont++;
if (pCont >= 2) {
setElevation(100);
bringToFront();
getParent().requestDisallowInterceptTouchEvent(true);
lastD = getDistance(event);
lastCenter = getCurrentPoint(event);
}
return true;
case MotionEvent.ACTION_POINTER_UP:
pCont--;
return true;
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() >= 2) {
double moved = getDistance(event) - lastD;
double viewSize = Math.sqrt(getWidth() * getWidth() + getHeight() * getHeight());
double scale = (moved / viewSize);
Log.d(TAG, scale + " " + lastD);
setVisibility(INVISIBLE);
Point point = getCurrentPoint(event);
float tx = point.x - lastCenter.x;
float ty = point.y - lastCenter.y;
MakeUpZoomImage.get().update(this, getDrawable(), scale + 1, tx, ty);
return true;
}
return true;
case MotionEvent.ACTION_UP:
MakeUpZoomImage.get().remove();
setVisibility(VISIBLE);
getParent().requestDisallowInterceptTouchEvent(false);
pCont = 0;
setScaleX(1);
setScaleY(1);
return true;
default:
break;
}
return super.onTouchEvent(event);
}
private Point getCurrentPoint(MotionEvent event) {
float x0 = event.getX(0);
float y0 = event.getY(0);
float x1 = event.getX(1);
float y1 = event.getY(1);
Point point = new Point(((int) (x1 + x0) / 2), ((int) (y1 + y0) / 2));
return point;
}
private double getDistance(MotionEvent event) {
float x0 = event.getX(0);
float y0 = event.getY(0);
float x1 = event.getX(1);
float y1 = event.getY(1);
return Math.sqrt((
(y1 - y0) * (y1 - y0))
+ ((x1 - x0) * (x1 - x0))
);
}
}
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class MakeUpZoomImage {
private Activity activity;
private volatile static MakeUpZoomImage makeUpZoomImage;
private ImageView imageView;
private MakeUpZoomImage(Activity activity) {
this.activity = activity;
imageView = new ImageView(activity);
activity.addContentView(imageView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setVisibility(View.GONE);
}
public static MakeUpZoomImage attach(Activity activity) {
if (makeUpZoomImage == null) {
synchronized (MakeUpZoomImage.class) {
if (makeUpZoomImage == null) {
makeUpZoomImage = new MakeUpZoomImage(activity);
}
}
}
return makeUpZoomImage;
}
public static MakeUpZoomImage get() {
if (makeUpZoomImage == null) {
synchronized (MakeUpZoomImage.class) {
if (makeUpZoomImage == null) {
throw new IllegalStateException("Must be initialized");
}
}
}
return makeUpZoomImage;
}
public void release() {
remove();
makeUpZoomImage = null;
}
public void update(View view, Drawable drawable, double zoom, float tx, float ty) {
if (view == null) {
return;
}
int[] location = new int[2];
view.getLocationInWindow(location);
ViewGroup.LayoutParams lp = imageView.getLayoutParams();
lp.width = view.getWidth();
lp.height = view.getHeight();
imageView.setLayoutParams(lp);
imageView.setX(location[0] + tx);
imageView.setY(location[1] - getNotificationBarHeight() + ty);
imageView.setVisibility(View.VISIBLE);
imageView.setImageDrawable(drawable);
imageView.setScaleX((float) zoom);
imageView.setScaleY((float) zoom);
}
private int getNotificationBarHeight() {
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
int height = resources.getDimensionPixelSize(resourceId);
return height;
}
public void remove() {
imageView.setVisibility(View.GONE);
imageView.setImageDrawable(null);
}
}