栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android实现ImageView图片缩放和拖动

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android实现ImageView图片缩放和拖动

今天我们来编写一个缩放效果的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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160811.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号