热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android手势滑动实现ImageView缩放图片大小

这篇文章主要为大家详细介绍了Android手势滑动实现ImageView缩放图片大小的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文推出了两种Android手势实现ImageView缩放图片大小的方法,分享给大家供大家参考,具体内容如下

方法一:

将以下代码写到MulitPointTouchListener.java中,然后对你相应的图片进行OnTouchListener。
例如:imageView.setOnTouchListener(new MulitPointTouchListener ());

在xml中要将ImageView的缩放格式改成Matrix

例如:android:scaleType="matrix"

这样就可以实现图片的缩放了

下面是MulitPointTouchListener.java代码:

public class MulitPointTouchListener implements OnTouchListener { 
  private static final String TAG = "Touch"; 
  // These matrices will be used to move and zoom image 
  Matrix matrix = new Matrix(); 
  Matrix savedMatrix = new Matrix(); 
 
  // We can be in one of these 3 states 
  static final int NOnE= 0; 
  static final int DRAG = 1; 
  static final int ZOOM = 2; 
  int mode = NONE; 
 
  // Remember some things for zooming 
  PointF start = new PointF(); 
  PointF mid = new PointF(); 
  float oldDist = 1f; 
 
  @Override 
  public boolean onTouch(View v, MotionEvent event) { 
 
    ImageView view = (ImageView) v; 
    // Log.e("view_width", 
    // view.getImageMatrix()..toString()+"*"+v.getWidth()); 
    // Dump touch event to log 
    dumpEvent(event); 
 
    // Handle touch events here... 
    switch (event.getAction() & MotionEvent.ACTION_MASK) { 
    case MotionEvent.ACTION_DOWN: 
 
      matrix.set(view.getImageMatrix()); 
      savedMatrix.set(matrix); 
      start.set(event.getX(), event.getY()); 
      //Log.d(TAG, "mode=DRAG"); 
      mode = DRAG; 
 
       
      //Log.d(TAG, "mode=NONE"); 
      break; 
    case MotionEvent.ACTION_POINTER_DOWN: 
      oldDist = spacing(event); 
      //Log.d(TAG, "oldDist=" + oldDist); 
      if (oldDist > 10f) { 
        savedMatrix.set(matrix); 
        midPoint(mid, event); 
        mode = ZOOM; 
        //Log.d(TAG, "mode=ZOOM"); 
      } 
      break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_POINTER_UP: 
      mode = NONE; 
      //Log.e("view.getWidth", view.getWidth() + ""); 
      //Log.e("view.getHeight", view.getHeight() + ""); 
 
      break; 
    case MotionEvent.ACTION_MOVE: 
      if (mode == DRAG) { 
        // ... 
        matrix.set(savedMatrix); 
        matrix.postTranslate(event.getX() - start.x, event.getY() 
            - start.y); 
      } else if (mode == ZOOM) { 
        float newDist = spacing(event); 
        //Log.d(TAG, "newDist=" + newDist); 
        if (newDist > 10f) { 
          matrix.set(savedMatrix); 
          float scale = newDist / oldDist; 
          matrix.postScale(scale, scale, mid.x, mid.y); 
        } 
      } 
      break; 
    } 
 
    view.setImageMatrix(matrix); 
    return true; // indicate event was handled 
  } 
 
  private void dumpEvent(MotionEvent event) { 
    String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", 
        "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; 
    StringBuilder sb = new StringBuilder(); 
    int action = event.getAction(); 
    int actiOnCode= action & MotionEvent.ACTION_MASK; 
    sb.append("event ACTION_").append(names[actionCode]); 
    if (actiOnCode== MotionEvent.ACTION_POINTER_DOWN 
        || actiOnCode== MotionEvent.ACTION_POINTER_UP) { 
      sb.append("(pid ").append( 
          action >> MotionEvent.ACTION_POINTER_ID_SHIFT); 
      sb.append(")"); 
    } 
    sb.append("["); 
    for (int i = 0; i 

方法二:自定义一个ImageView,例如TouchImageView:

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;

public class TouchImageView extends ImageView {

 Matrix matrix;

 // We can be in one of these 3 states
 static final int NOnE= 0;
 static final int DRAG = 1;
 static final int ZOOM = 2;
 int mode = NONE;

 // Remember some things for zooming
 PointF last = new PointF();
 PointF start = new PointF();
 float minScale = 1f;
 float maxScale = 3f;
 float[] m;


 int viewWidth, viewHeight;
 static final int CLICK = 3;
 float saveScale = 1f;
 protected float origWidth, origHeight;
 int oldMeasuredWidth, oldMeasuredHeight;


 ScaleGestureDetector mScaleDetector;

 Context context;

 public TouchImageView(Context context) {
  super(context);
  sharedConstructing(context);
 }

 public TouchImageView(Context context, AttributeSet attrs) {
  super(context, attrs);
  sharedConstructing(context);
 }
 
 private void sharedConstructing(Context context) {
  super.setClickable(true);
  this.cOntext= context;
  mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
  matrix = new Matrix();
  m = new float[9];
  setImageMatrix(matrix);
  setScaleType(ScaleType.MATRIX);

  setOnTouchListener(new OnTouchListener() {

   @Override
   public boolean onTouch(View v, MotionEvent event) {
    mScaleDetector.onTouchEvent(event);
    PointF curr = new PointF(event.getX(), event.getY());

    switch (event.getAction()) {
     case MotionEvent.ACTION_DOWN:
      last.set(curr);
      start.set(last);
      mode = DRAG;
      break;
      
     case MotionEvent.ACTION_MOVE:
      if (mode == DRAG) {
       float deltaX = curr.x - last.x;
       float deltaY = curr.y - last.y;
       float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);
       float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);
       matrix.postTranslate(fixTransX, fixTransY);
       fixTrans();
       last.set(curr.x, curr.y);
      }
      break;

     case MotionEvent.ACTION_UP:
      mode = NONE;
      int xDiff = (int) Math.abs(curr.x - start.x);
      int yDiff = (int) Math.abs(curr.y - start.y);
      if (xDiff  maxScale) {
    saveScale = maxScale;
    mScaleFactor = maxScale / origScale;
   } else if (saveScale  maxTrans)
   return -trans + maxTrans;
  return 0;
 }
 
 float getFixDragTrans(float delta, float viewSize, float contentSize) {
  if (contentSize <= viewSize) {
   return 0;
  }
  return delta;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  viewWidth = MeasureSpec.getSize(widthMeasureSpec);
  viewHeight = MeasureSpec.getSize(heightMeasureSpec);
  
  //
  // Rescales image on rotation
  //
  if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
    || viewWidth == 0 || viewHeight == 0)
   return;
  oldMeasuredHeight = viewHeight;
  oldMeasuredWidth = viewWidth;

  if (saveScale == 1) {
   //Fit to screen.
   float scale;

   Drawable drawable = getDrawable();
   if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)
    return;
   int bmWidth = drawable.getIntrinsicWidth();
   int bmHeight = drawable.getIntrinsicHeight();
   
   Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);

   float scaleX = (float) viewWidth / (float) bmWidth;
   float scaleY = (float) viewHeight / (float) bmHeight;
   scale = Math.min(scaleX, scaleY);
   matrix.setScale(scale, scale);

   // Center the image
   float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);
   float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);
   redundantYSpace /= (float) 2;
   redundantXSpace /= (float) 2;

   matrix.postTranslate(redundantXSpace, redundantYSpace);

   origWidth = viewWidth - 2 * redundantXSpace;
   origHeight = viewHeight - 2 * redundantYSpace;
   setImageMatrix(matrix);
  }
  fixTrans();
 }
}

然后在我们的Activity中就可以直接使用了:

public class TouchImageViewActivity extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  TouchImageView img = (TouchImageView) findViewById(R.id.snoop);
  img.setImageResource(R.drawable.snoopy);
  img.setMaxZoom(4f);
 }
}

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


推荐阅读
  • Android 九宫格布局详解及实现:人人网应用示例
    本文深入探讨了人人网Android应用中独特的九宫格布局设计,解析其背后的GridView实现原理,并提供详细的代码示例。这种布局方式不仅美观大方,而且在现代Android应用中较为少见,值得开发者借鉴。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 本文将详细介绍如何使用剪映应用中的镜像功能,帮助用户轻松实现视频的镜像效果。通过简单的步骤,您可以快速掌握这一实用技巧。 ... [详细]
  • 本文探讨了 RESTful API 和传统接口之间的关键差异,解释了为什么 RESTful API 在设计和实现上具有独特的优势。 ... [详细]
  • 本文详细介绍了如何使用Spring Boot进行高效开发,涵盖了配置、实例化容器以及核心注解的使用方法。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文介绍如何在 Unity 的 XML 配置文件中,将参数传递给自定义生命周期管理器的构造函数。我们将详细探讨 CustomLifetimeManager 类的实现及其配置方法。 ... [详细]
author-avatar
依love依CENE_790
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有