今天我们来编写一个缩放效果的ImageView ,网上有很多人都讲了这些。但有许多人都直接使用了库文件,
那么我们今天做的是直接上代码编写一个拖动和缩放的ImageView,具体看效果图
那么简单了分析一下。在手机上缩放图片和拖动要用到什么?手指对不对
那么控件上什么事件和手机有关。View.onTouchListener 对不对。
ok,那么先新建一个Class
···
public class baseDragZoomImageView extends ImageView implements View.onTouchListener
···
没错,继承ImageView 并且添加View.OnTouchListener事件
然后我们看看构造函数
public baseDragZoomImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setonTouchListener(this);
}
public baseDragZoomImageView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
setonTouchListener(this);
}
public baseDragZoomImageView(Context context)
{
this(context, null);
setonTouchListener(this);
}
对,在构造函数中,我们将setonTouchListener 设置了。
那么这个setonTouchListener 具体怎么做。我们就先分析一下onTouch 中MotionEvent。
我们都知道手指的操作有很多,那么Andorid自然也将这种情况分了很多种case。
- MotionEvent.ACTION_DOWN 手指按下屏幕
- MotionEvent.ACTION_MOVE 手指在屏幕上移动
- MotionEvent.ACTION_UP 手指离开屏幕
- MotionEvent.ACTION_POINTER_UP 当触点离开屏幕,但是屏幕上还有触点(手指)
- MotionEvent.ACTION_POINTER_DOWN 当屏幕上已经有触点(手指),再有一个触点压下屏幕
很显然,这些看起来好像都能够用得到。
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 手指压下屏幕
case MotionEvent.ACTION_DOWN:
mode = MODE_DRAG;
// 记录ImageView当前的移动位置
currentMatrix.set(getImageMatrix());
startPoint.set(event.getX(), event.getY());
break;
// 手指在屏幕上移动,改事件会被不断触发
case MotionEvent.ACTION_MOVE:
// 拖拉图片
if (mode == MODE_DRAG) {
float dx = event.getX() - startPoint.x; // 得到x轴的移动距离
float dy = event.getY() - startPoint.y; // 得到x轴的移动距离
// 在没有移动之前的位置上进行移动
matrix.set(currentMatrix);
matrix.postTranslate(dx, dy);
}
// 放大缩小图片
else if (mode == MODE_ZOOM) {
float endDis = distance(event);// 结束距离
if (endDis > 10f) { // 两个手指并拢在一起的时候像素大于10
float scale = endDis / startDis;// 得到缩放倍数
matrix.set(currentMatrix);
matrix.postScale(scale, scale,midPoint.x,midPoint.y);
}
}
break;
// 手指离开屏幕
case MotionEvent.ACTION_UP:
// 当触点离开屏幕,但是屏幕上还有触点(手指)
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
// 当屏幕上已经有触点(手指),再有一个触点压下屏幕
case MotionEvent.ACTION_POINTER_DOWN:
mode = MODE_ZOOM;
startDis = distance(event);
if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
midPoint = mid(event);
//记录当前ImageView的缩放倍数
currentMatrix.set(getImageMatrix());
}
break;
}
setImageMatrix(matrix);
return true;
}
ok,收工。具体就只有这么多。我们来看下整个class
package com.jonkming.easyui.image.dragzoom.ui;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.util.FloatMath;
public class baseDragZoomImageView extends ImageView implements View.OnTouchListener{
private int mode = 0;// 初始状态
private static final int MODE_DRAG = 1;
private static final int MODE_ZOOM = 2;
private PointF startPoint = new PointF();
private Matrix matrix = new Matrix();
private Matrix currentMatrix = new Matrix();
private float startDis;
private PointF midPoint;
public baseDragZoomImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setonTouchListener(this);
}
public baseDragZoomImageView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
setonTouchListener(this);
}
public baseDragZoomImageView(Context context)
{
this(context, null);
setonTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 手指压下屏幕
case MotionEvent.ACTION_DOWN:
mode = MODE_DRAG;
// 记录ImageView当前的移动位置
currentMatrix.set(getImageMatrix());
startPoint.set(event.getX(), event.getY());
break;
// 手指在屏幕上移动,改事件会被不断触发
case MotionEvent.ACTION_MOVE:
// 拖拉图片
if (mode == MODE_DRAG) {
float dx = event.getX() - startPoint.x; // 得到x轴的移动距离
float dy = event.getY() - startPoint.y; // 得到x轴的移动距离
// 在没有移动之前的位置上进行移动
matrix.set(currentMatrix);
matrix.postTranslate(dx, dy);
}
// 放大缩小图片
else if (mode == MODE_ZOOM) {
float endDis = distance(event);// 结束距离
if (endDis > 10f) { // 两个手指并拢在一起的时候像素大于10
float scale = endDis / startDis;// 得到缩放倍数
matrix.set(currentMatrix);
matrix.postScale(scale, scale,midPoint.x,midPoint.y);
}
}
break;
// 手指离开屏幕
case MotionEvent.ACTION_UP:
// 当触点离开屏幕,但是屏幕上还有触点(手指)
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
// 当屏幕上已经有触点(手指),再有一个触点压下屏幕
case MotionEvent.ACTION_POINTER_DOWN:
mode = MODE_ZOOM;
startDis = distance(event);
if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
midPoint = mid(event);
//记录当前ImageView的缩放倍数
currentMatrix.set(getImageMatrix());
}
break;
}
setImageMatrix(matrix);
return true;
}
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return (float) Math.sqrt(dx * dx + dy * dy);
}
private PointF mid(MotionEvent event) {
float midX = (event.getX(1) + event.getX(0)) / 2;
float midY = (event.getY(1) + event.getY(0)) / 2;
return new PointF(midX, midY);
}
}
然后看布局文件
就是这么简单。
代码所在位置: GitHub
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



