Android应用开发之图片拖拉和多点触摸缩放

缩放图片的ImageView 可以进行两指缩放,并且可以进行拖拉的ImageView最简单原生的实现 今天小试了下所谓的图片察看器,可以对图片进行放大缩小和 阅读详情

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229

        今天我们学习如何实现图片(理论上选取的图片实际尺寸应大于当前手机的屏幕尺寸)拖拉和多点触摸缩放功能。其中多点触摸缩放功能模拟器上不支持,需要在真机下测试。下面给出该场景的案例:

1案例技术要点

(1)图片变换矩阵(android.graphics.Matrix):提供记录图片位置、记录图片缩放比例、实现图片移动等。

(2)图片坐标点(android.graphics.PointF):提供记录图片起点和中心点坐标等。

(3)重写图片所在Activity的onTouch(...)方法,处理以下几个事件:

MotionEvent.ACTION_DOWN:触点(手指)按下时触发该事件

MotionEvent.ACTION_POINTER_DOWN:当屏幕上已经有触点(手指),再有触点(手指)按下时触发该事件

MotionEvent.ACTION_MOVE:触点(手指)移动时触发该事件

MotionEvent.ACTION_UP:触点(手指)离开屏幕时触发该事件

MotionEvent.ACTION_POINTER_UP:当触点(手指)离开屏幕,但屏幕上仍有其他触点(手指)时触发该事件

2案例代码陈列

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.dragscale"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/avatar"
        android:label="@string/app_name" >
        <activity
            android:name=".DragScaleMainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

strings.xml

<resources>
    <string name="app_name">ImageView拖拉与多点触摸缩放</string>
</resources>

main.xml

<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/xianyun4"
        android:scaleType="matrix" />

</LinearLayout>

DragScaleMainActivity.java

package com.android.dragscale;

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class DragScaleMainActivity extends Activity {
    private ImageView imageView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        imageView = (ImageView) findViewById(R.id.imageView);
        imageView.setOnTouchListener(new OnTouchListener() {
            // 设置开始点
            private PointF startPoint = new PointF();
            // 设置图片位置的变换矩阵
            private Matrix matrix = new Matrix();
            // 设置图片当前位置的变换矩阵
            private Matrix currentMatrix = new Matrix();
            // 初始化模式参数
            private int mode = 0;
            // 无模式
            private static final int NONE = 0;
            // 拖拉模式
            private static final int DRAG = 1;
            // 缩放模式
            private static final int ZOOM = 2;
            // 开启缩放效果的门槛
            private static final float ZOOM_THRESHOLD = 10.0f;
            // 开始距离
            private float startDistance;
            // 中心点
            private PointF middlePoint;
            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mode = DRAG;
                    // 记录图片当前的移动位置
                    currentMatrix.set(imageView.getImageMatrix());
                    // 记录开始坐标
                    startPoint.set(event.getX(), event.getY());
                    break;
                    
                 // 当屏幕上已经有触点(手指),再有手指按下时触发该事件
                case MotionEvent.ACTION_POINTER_DOWN:
                    mode = ZOOM;
                    startDistance = getDistance(event);
                    if(startDistance > ZOOM_THRESHOLD) {
                        middlePoint = getMiddlePoint(event);
                        // 记录图片当前的缩放比例
                        currentMatrix.set(imageView.getImageMatrix());
                    }
                    break;

                case MotionEvent.ACTION_MOVE:
                    if(mode == DRAG) {
                        // 获取X轴移动距离
                        float distanceX = event.getX() - startPoint.x;
                        // 获取Y轴移动距离
                        float distanceY = event.getY() - startPoint.y;
                        // 在上次移动停止位置的基础上再进行移动
                        matrix.set(currentMatrix);
                        // 实现图片位置移动
                        matrix.postTranslate(distanceX, distanceY);
                    } else if(mode == ZOOM) {
                        // 结束距离
                        float endDistance = getDistance(event);
                        if(endDistance > ZOOM_THRESHOLD) {
                            // 缩放比例
                            float scale = endDistance / startDistance;
                            matrix.set(currentMatrix);
                            matrix.postScale(scale, scale, middlePoint.x, middlePoint.y);
                        }
                    }
                    break;
                    
                case MotionEvent.ACTION_UP:
                // 当手指离开屏幕,但屏幕上仍有其他触点(手指)时触发该事件
                case MotionEvent.ACTION_POINTER_UP:
                    mode = 0;
                    break;
                    
                }
                imageView.setImageMatrix(matrix);
                return true;
            }

        });
    }
    
    /**
     * 计算两点之间的距离
     * @param event
     * @return
     */
    public static float getDistance(MotionEvent event) {
        //第二个点x、y坐标减去第一个点x、y坐标
        float disX = event.getX(1) - event.getX(0);
        float disY = event.getY(1) - event.getY(0);
        return FloatMath.sqrt(disX * disX + disY * disY);
    }
    
    /**
     * 计算两点之间的中间点
     * @param event
     * @return
     */
    public static PointF getMiddlePoint(MotionEvent event) {
        float midX = (event.getX(0) + event.getX(1)) /2;
        float midY = (event.getY(0) + event.getY(1)) /2;
        return new PointF(midX, midY);
    }
}
        注意:提供一张图片(壁纸)存放于drawable-hdpi文件夹下。

3案例效果展示

 
android学习笔记---58_拖拉功能与多点触摸,实现图片的拖拉和缩放功能 Java技术qq交流群:JavaDream:251572072 2013/5/14 58_拖拉功能与多点触摸 ------------------------------------- android零碎要点: 理论上 Android可以处理 多达256 个手指的触摸,大概只有章鱼哥能享受这种技术带来的便利。就编程人员来说,编写多点触摸和单点触摸的方式几乎一模一样。其奥秘在于Motion 阅读详情

相关推荐

光伏发电系统模拟及其发电预测开源python工具pvlib

本文介绍光伏发电系统模拟及其发电预测开源python工具pvlib,以及举例介绍获取辐照度方法、光伏发电预测思路。

肖永威的专栏 1万+

别再死记硬背波形了!用LTspice仿真带你直观理解LLC谐振变换器的三种工作模式

本文通过LTspice仿真工具深入解析LLC谐振变换器的三种工作模式(fs>fr、fs=fr、fr1<fs<fr),帮助工程师直观理解开关电源的工作原理。从基础模型搭建到高级参数扫描,提供详实的仿真步骤和故障排查技巧,助力开发者掌握LLC变换器的核心设计要点。

weixin_30384217的博客 325

解决uc浏览器劫持video标签问题

解决uc视频悬浮播放 ,video标签被浏览器劫持 ,vide0适配

smile_y_y的博客 3450

PanoramaGL library类库详细解析

简介 PanoramaGL libraryis the firstopen sourcelibrary in the world to see panoramic views on the iPod Touch 1G, 2G, 3G and iPhone EDGE, 3G and 3GS.PanoramaGL图书馆是世界上第一个开源库和3GS看到全景1G的iPod上的触摸,2G...

sabolasi 334

AXI Memory Mapped To PCI Express IP 核设计实例

本文详细描述了AXI Memory Mapped To PCI Express(2.9) IP核的应用实例

u011565038的博客 2801

把数字化转型真正落到组织里:读懂 SAP 的 OCM 六维框架

摘要: SAP的变革管理框架(OCM)强调数字化转型不仅是技术任务,更需关注组织与人的适应性。OCM包含六大维度:变革战略(明确方向与风险)、变革领导力(统一关键管理者行动)、变革沟通(分层传递信息)、变革实现(细化岗位级影响)、变革赋能(按角色设计培训)和变革有效性(持续评估)。该框架贯穿项目全周期,尤其在云项目中,需从早期规划变革策略,避免后期高代价调整。OCM的核心是将系统设计转化为组织语言,确保业务真正采纳新方式运作。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1433

图片压缩

开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法:   方法1:按固定比例进行缩放   在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们取图片的缩略图,取缩略图的方法我们可以使用BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Op

yzx41099296的专栏 814

torch_npu 用法笔记

torch_npu 用法笔记

jacke121的专栏 1536

android 按钮按下缩放,android 多点触摸图片缩放的具体实现方法

package taokun.demo.MutilTouchDemo;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.PointF;import...

weixin_36343299的博客 370

基于VSCode+clangd插件打造高效C++开发环境之四:clangd配置

本文介绍如何配置VSCode+clangd插件进行高效C++开发。重点内容包括:1)生成compile_commands.json文件,通过ninja工具提取编译命令并使用gen_compdb脚本转换;2)配置clangd命令行参数,如设置后台索引、并行度等;3)编写.clangd配置文件,调整编译标志和诊断选项;4)添加.clang-format文件定义代码风格;5)在VSCode中添加远程服务器工作目录。配置完成后需重启clangd服务使更改生效。文章还提供了MTK/QCOM等不同平台生成compile

5071

APP爬虫:Airtest的使用和爬取实战详解

Airtest是一个跨平台的自动化测试工具,主要用于移动应用和游戏的UI自动化测试。它支持图像识别、触摸操作、文本输入等功能,能够模拟真实用户的操作行为。此外,Airtest还具备强大的日志记录和报告生成功能,方便开发者进行调试和分析。图像识别:通过截图匹配元素,无需依赖 UI 层次结构。跨平台支持:支持 Android、iOS 和 Windows 应用。简单易用:提供 IDE 和脚本录制功能,降低使用门槛。

数据知道的博客 9619

android中图片的拖拉和缩放

首先是布局文件,引入图片 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"

每天进步一点点 713

120、NPU的Mythic M1076:模拟存算一体NPU

这篇文章分享了作者调试Mythic M1076模拟存算一体NPU的实战经验,主要包含以下要点: 硬件设计陷阱:参考电压输入必须使用低ESR电容,普通贴片电容会导致模拟计算阵列工作异常。 核心技术原理: 采用真正的存算一体架构,将权重存储为模拟电压 使用浮栅晶体管存储权重,通过电流叠加实现乘法运算 包含108个计算单元阵列(Tile),每个256×256规模 使用注意事项: 编程模型特殊,需要依赖SDK自动映射网络层 存在6-8位有效精度限制,需用量化感知训练 功耗特性独特,静态偏置电流占主要功耗 调试手段有

m0_50546716的博客 122

android 图片任意拖拉,android中图片的拖拉和缩放

首先是布局文件,引入图片activitypackage cn.wonders.drag;import android.support.v7.app.ActionBarActivity;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import and...

weixin_31108095的博客 220

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Android多点触控缩放拖拽实例

在Android上查看图片或者浏览网页时,我们往往有把图片或者网页放大或者缩小的的需求,这样就能够获得更多的细节信息 或者获得更多的全貌信息,多点触摸与绽放功能正是满足这种应用场景的技术。

cqtddt的专栏 1520

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Android 多点触摸 multi-touch

多点触摸multi-touch 最近研究多点触摸,做了个demo。Demo中实现多点触摸缩放和使用按钮点击放大和缩小。注意2.0以上才支持多点触摸。 程序代码如下:   package org.example.touch; import android.app.Activity; import android.graphics.Bitmap; import andr

zwq1457的专栏 656

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

安卓运用matrix进行图片的拖动和缩放

1.matrix讲解 Matrix的对图像的处理可分为四类基本变换: Translate           平移变换 Rotate                旋转变换 Scale                  缩放变换 Skew                  错切变换 针对每种变换,Android提供了pre、set和post三种操作方式。其中

YanRu的专栏 1458

android图片触摸缩放,Android实现手指触控图片缩放功能

这次记录的是实现Android图片两手触控缩放的功能。编译环境:eclipseAndroid版本4.0创建工程过程略实现图片在页面两手触控缩放原理图---图片缩放两手拉开图片变大,两手合拢图片缩小,根据两手的移动距离来判断图片放大和缩小的倍数,两手的移动距离计算方法如下:两手不管是正着还是斜着拉伸,用勾股定理都能计算出两点的距离。除此之外,还要确定两个手位置的中心点,图片以这个中心点为参照进行放大...

weixin_29485605的博客 501

Android多点触摸放大缩小图片

1.Activity package com.fit.touchimage; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFact

这里才是学习Android的好地方 1万+

android 图片触摸放大,Android多点触摸放大缩小图片

1.Activitypackage com.fit.touchimage;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.PointF;impo...

weixin_29945371的博客 422

Android 对图片的缩放,拖地,跟系统图库的效果一样

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666) 本文转自:http://blog.youkuaiyun.com/xiaanming/article/details/8827257 这里只是将原文页面上的代码移植到自定义控件中,便于以后使用,暂时没做功能性扩展,要看讲解可以...

孤云博客 580

android 多点触摸 放大 缩小 图片

package org.example.touch; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PointF; imp

To lose to pursue. 1021

android 手势触发图片缩放拖动(包含缩放图片时图片的大小判断以及拖动图片时图片的边界判断)

定义ImageView,实现功能如下: 1.初始化时图片垂直居中显示,拉伸图片宽度至ImageView宽度。 2.使用两根手指放大缩小图片,可设置最大放大倍数,当图片小于ImageView宽度时,在手指离开屏幕时恢复到ImageView宽度。 3.支持双击放大缩小。当图片处于未放大状态时,双击放大至指定倍数,当图片处于放大状态时,双击恢复至未放大状态。 4.图片拖动效果。当

nangongyanya的专栏 6506

android 自由缩放图片大小,android Matrix实现图片随意放大缩小或拖动

本文实例为大家分享了android Matrix图片随意放大缩小和拖动的具体代码,供大家参考,具体内容如下step1:新建一个项目DragAndZoom,并准备一张照片放在res/drawable-hdpi目录下,如下图所示:step2:设置应用的UI界面,在main.xml中设置:android:orientation="vertical"android:layout_width="fill_p...

weixin_34079307的博客 1444
上一篇: Android应用开发之单元测试之白盒巧克力
下一篇: GoF23种设计模式之行为型模式之责任链模式
innovation
博客等级 码龄14年 251粉丝 136原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值