`
Darar
  • 浏览: 87815 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

多点触摸放大图片的自定义listener

阅读更多
可以看到很多相册应用,通过两根手指的操作,能让图片放大缩小。很简单,通过自定义的继承于onTouchListener的类,去实现这样的效果。代码如下:

package cn.test;

import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

public class MulitPointTouchListener implements OnTouchListener {

    // These matrices will be used to move and zoom image
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();

    public ImageView image;
    // 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;

    
    public MulitPointTouchListener(ImageView image) {
  super();
  this.image = image;
 }

 @Override
    public boolean onTouch(View v, MotionEvent event) {
  this.image.setScaleType(ScaleType.MATRIX);

            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;

                    /*
                     * float scaleWidth=180f/320; float scaleHeight=240f/480;
                     * matrix.reset(); matrix.postScale(scaleWidth, scaleHeight);
                     */
                    //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 < event.getPointerCount(); i++) {
                    sb.append("#").append(i);
                    sb.append("(pid ").append(event.getPointerId(i));
                    sb.append(")=").append((int) event.getX(i));
                    sb.append(",").append((int) event.getY(i));
                    if (i + 1 < event.getPointerCount())
                            sb.append(";");
            }
            sb.append("]");
            //Log.d(TAG, sb.toString());
    }

    /** Determine the space between the first two fingers */
    private float spacing(MotionEvent event) {
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return FloatMath.sqrt(x * x + y * y);
    }

    /** Calculate the mid point of the first two fingers */
    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);
    }
}
分享到:
评论
1 楼 xunhuan01 2012-04-11  
view.getImageMatrix(), savedMatrix.set(matrix);  这两句是什么意思?
为什么是event.getx()-start.x,event.gety()-start.y

相关推荐

    基于as3的多点触摸

    4. **监听器(Event Listener)**:我们需要为舞台或特定显示对象添加触摸事件监听器,以便在触摸事件发生时执行相应的处理函数。例如,可以使用`addEventListener`方法添加监听器。 5. **多点触摸处理**:处理多个...

    android 图片缩放和多点触摸源码.rar

    在Android开发中,图片处理和用户交互是两个非常重要的方面,尤其在开发图像查看器或者画廊应用时,图片的缩放和多点触摸功能更是不可或缺。本项目"android 图片缩放和多点触摸源码"正是针对这两个功能进行实现的...

    自定义dialo,可以传listener

    在给定的标题"自定义dialo,可以传listener"和描述"自定义dialog,可以传listener"中,我们可以深入探讨如何在Android中创建一个自定义的`Dialog`并添加监听器。 1. **自定义Dialog** 自定义`Dialog`通常是因为...

    自定义GestureDetector实现多点触控

    本篇文章将深入探讨如何自定义GestureDetector来实现多点触控功能,以及自定义手势的实现原理。 一、Android多点触控基础 在Android系统中,多点触控主要依赖于MotionEvent类,它包含了处理触摸事件的所有信息,如...

    Android ImageView动态更新图片自定义监听

    本文将深入探讨如何实现动态更新`ImageView`中的图片,并利用自定义监听器来跟踪和处理加载过程。这在应用中非常实用,比如在加载网络头像、商品图片或动态刷新数据时。 首先,我们要理解`ImageView`的基本用法。在...

    自定义的listener的布局

    源码PercentVisibleLayout,VisibilityPercentageLayout是一个带有自定义的listener的布局(继承自RelativeLayout),每当布局发生变化的时候能给出布局可见百分比。也支持可见像素的listener。

    cocos2d-x-3.2文档

    在Cocos2d-x 3.2版本中,多点触摸功能被广泛应用于游戏和交互式应用中,允许用户同时处理多个触摸输入。这个功能的实现主要依赖于事件处理和事件分发机制的改进。以下是关于Cocos2d-x 3.2中多点触摸的详细说明: ...

    自定义ScrollView 实现图片放大,上滑修改标题栏状态

    本教程将重点讲解如何通过自定义ScrollView来实现图片的拉伸放大效果,并在用户上滑时动态修改标题栏的状态。这一功能常用于诸如新闻详情页或者电商商品详情页等场景,能够提升用户的浏览体验。 首先,我们需要创建...

    TcpListener异步通信

    本文将深入探讨如何使用C#实现一个简单的TcpListener来支持异步通信,允许多客户端同时连接。 首先,我们需要理解TcpListener类在C#中的作用。TcpListener是.NET Framework提供的一个类,用于监听特定IP地址和端口...

    SpringBoot整合Listener的两种方式.docx

    在Spring Boot应用中,整合Listener主要是为了监听应用的生命周期事件,例如在应用启动或关闭时执行特定的操作。这里我们讨论两种整合Listener的方式。 ### 方式一:通过注解扫描完成Listener组件的注册 1. **创建...

    java swt自定义控件

    // 绘制图片 gc.drawImage(image, 0, 0); // 添加其他绘制操作,如文字 } } ``` ### 7. 结合Eclipse RCP 如果你正在开发Eclipse Rich Client Platform (RCP) 应用程序,自定义控件可以增强应用程序的用户体验。...

    listener我的listener listener我的listener

    标题中的"listener我的listener listener我的listener"可能是在强调Listener的重要性或者是在多次提及一个与Listener相关的个人项目或资源。 在Java中,Listener模式是设计模式的一种,属于行为型模式,它允许我们...

    RAC listener.ora详解.docx

    Oracle RAC 监听器配置文件 listener.ora 详解 Oracle RAC 监听器配置文件 listener.ora 是一个核心配置文件,用于配置 Oracle Net Listener 的参数。本文将详细介绍 listener.ora 文件的配置参数、协议地址参数、...

    java拼图游戏可自定义图片及块数

    Java拼图游戏是一款基于Java编程语言开发的娱乐应用,它允许用户自定义拼图的图片来源和分割块的数量,从而提供了高度的个性化体验。这款游戏中,用户可以选择任何想要的图片,将其转化为拼图,然后尝试将这些散乱的...

    TcpListener 监听服务端

    TcpListener 是 .NET Framework 中用于创建 TCP 服务器端应用程序的关键组件。它允许程序监听来自多个客户端的连接请求,实现网络通信。在这个场景中,我们关注的是如何使用 TcpListener 创建一个可以处理多客户端...

    针对Oracle的TNS listener的攻击原理及方法介绍

    Oracle TNS Listener是Oracle数据库系统中用于监听客户端请求的关键组件。其基本功能是在网络上监听客户端发来的连接请求,并对这些请求做出响应。然而,TNS Listener也存在一系列安全漏洞,尤其是缓冲区溢出和配置...

    c# tcplistener tcp监控

    这里`IPAddress.Any`表示监听所有网络接口,`12345`是自定义的端口号。 2. 调用`Start()`方法启动监听服务: ```csharp listener.Start(); ``` 3. 使用`AcceptTcpClient()`方法阻塞地等待客户端连接。当有客户端...

    自定义DatePickerDialog的实现

    然而,有时候系统默认的样式可能无法满足我们的设计需求,这时候就需要我们自定义`DatePickerDialog`来达到预期的效果。本教程将详细讲解如何在Android中实现自定义的`DatePickerDialog`。 首先,我们需要了解`...

    c# socket 、TCPClient、TCPListener 用法详解.doc

    C# Socket、TCPClient、TCPListener 用法详解 C# 中的 Socket 编程是基于 Windows Sockets (Winsock) 接口的托管实现,提供了一个强大且灵活的网络编程模型。在本文中,我们将详细介绍 C# 中的 Socket 编程,包括 ...

    handler与listener的区别

    在ExtJS框架中,`handler`和`listener`都是用于响应用户交互的关键概念,它们各自有不同的使用场景和特点。理解两者的区别对于有效管理和组织应用的事件处理至关重要。 1. **Handler** - `handler`通常与`Action`...

Global site tag (gtag.js) - Google Analytics