Android双击图片放大移动图中双击点到ImageView区域中心,Kotlin

Android双击图片放大移动图中双击点到ImageView区域中心,Kotlin

 

初始化状态,ImageView里面只是显示一张fitcenter被缩放的原图,当手指在图片上双击后(记录双击点位置:mCurX,mCurY)画一个红色小圆圈标记双击位置,放大图片,然后把放大后的图的(原mCurX,mCurY)位置移动到区域中心点位置,用大的红色圆圈标记。

 

双击:

1cd62e11f6a6437aa3f86b8a1086eaa7.png

 

 

放大图片,并把原来图中的双击点移动到区域中心,用大红圆圈标记:

ff67026c212149eaa35b2ae83eaf0f69.png

 


class MyImageView : AppCompatImageView {private var mCurX = 0fprivate var mCurY = 0fprivate val mCirclePaint = Paint()private var mSrcBmp: Bitmap? = nullprivate var mScaleBmp: Bitmap? = nullprivate var testIV: ImageView? = null//放大系数。private val mScaleFactor = 4fprivate var mGestureDetector: GestureDetector? = nullprivate var mIsDoubleTap = falseprivate var mCanDraw = falseconstructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {mSrcBmp = (drawable as BitmapDrawable).bitmap //mSrcBmp是原始图大小,没有缩放和拉伸的。mCirclePaint.style = Paint.Style.STROKEmCirclePaint.strokeWidth = 10fmCirclePaint.isAntiAlias = truemCirclePaint.color = Color.REDmGestureDetector = GestureDetector(ctx, object : GestureDetector.SimpleOnGestureListener() {override fun onDoubleTap(e: MotionEvent): Boolean {mIsDoubleTap = truereturn false}})}fun setTestImageView(iv: ImageView?) {testIV = iv}override fun onTouchEvent(event: MotionEvent): Boolean {mCurX = event.xmCurY = event.ymGestureDetector?.onTouchEvent(event)mCanDraw = trueinvalidate()return true}override fun onDraw(canvas: Canvas) {super.onDraw(canvas)if (mCanDraw) {canvas.drawCircle(mCurX, mCurY, 10f, mCirclePaint)}if (mIsDoubleTap) {myDraw(canvas)}}private fun myDraw(canvas: Canvas) {Thread.sleep(1000)if (mScaleBmp == null) {//创建一次,避免重复创建,提高速度。mScaleBmp = Bitmap.createScaledBitmap(mSrcBmp!!,(this.width * mScaleFactor + 1).toInt(), //注意这里的精度损失,会造成坐标偏移.(this.height * mScaleFactor + 1).toInt(),//注意这里的精度损失,会造成坐标偏移.true)}val cx = this.width / 2fval cy = this.height / 2fval matrix = Matrix()matrix.setScale(mScaleFactor, mScaleFactor)matrix.setTranslate(cx - mCurX * mScaleFactor, cy - mCurY * mScaleFactor)canvas.drawBitmap(mScaleBmp!!, matrix, null)//中心圆圈canvas.drawCircle(cx, cy, 40f, mCirclePaint)}
}

 

 

xml里面定义MyImageView,特别的属性设置:

        android:layout_width="match_parent"android:layout_height="wrap_content"android:adjustViewBounds="true"android:scaleType="fitCenter"

 

 

 

 

 

Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二)-CSDN博客文章浏览阅读197次。遗留问题,手指在上图滑动过程中,当滑动到一定区域,下面的切图框中已无太有效的图可以“放大”,后续可以填充黑色,表示无效放大。所有的绘制轨迹线,都限定在了绿色的圆角矩形框中,超出区域不予绘制。基础上,限定下面切图的绘制区域,超出绿色区域的轨迹线不再绘制。https://blog.csdn.net/zhangphil/article/details/135601993

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(1)-CSDN博客文章浏览阅读1.3k次,点赞19次,收藏17次。需要注意的,因为在xml布局里面特别设置了ImageView的高度为wrap_content,手指在屏幕触点的位置是放大镜里面放大图片后准确圆心位置,但是,如果ImageView设置成match_parent,则因为ImageView里面的Bitmap被缩放(此处Bitmap其实小于ImageView,被拉伸了),拉伸后的Bitmap水平方向坐标与ImageView一直重合,但竖直方向,Bitmap坐标与ImageView不一致,会造成一种现象,手指触点放大镜放大后,水平方向是正确的,但竖直方向有偏移量。https://blog.csdn.net/zhangphil/article/details/135172744

Android:GestureDetector.SimpleOnGestureListener,onFling,onScroll,velocityX,Y&distanceX,Y,kotlin_gesturedetector.simpleongesturelistener onscroll-CSDN博客文章浏览阅读184次。Android不用OnScrollListener采用GestureDetector结合OnTouchListener实现ListView下拉/上拉刷新通常Android的ListView的下拉/上拉刷新实现,使用OnScrollListener比较简单,比如如果要实现下拉见顶刷新,思路是在OnScrollListener判断当前ListView的滚动状态,如果滚动停止,则将此时Lis。_gesturedetector.simpleongesturelistener onscrollhttps://blog.csdn.net/zhangphil/article/details/130812011

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/636742.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux的权限命令详解】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 shell命令以及运行原理 Linux权限的概念 Linux权限管理 一、什么是权限? 二、权限的本质 三、Linux中的用户 四、linux中文件的权限 4.1、文件访问…

基于SpringBoot Vue高校失物招领系统

大家好✌!我是Dwzun。很高兴你能来阅读我,我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结,还为大家分享优质的实战项目,本人在Java项目开发领域有多年的经验,陆续会更新更多优质的Java实战项目&#x…

Django(八)

1. 管理员操作 1.1 添加 from django.shortcuts import render, redirectfrom app01 import models from app01.utils.pagination import Paginationfrom django import forms from django.core.exceptions import ValidationError from app01.utils.bootstrap import BootStr…

(学习日记)2024.01.19

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

2635. 转换数组中的每个元素

说在前面 🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。 题目描述 编写一个函数,这个函数接收一个整数数组 arr 和一个映射函数 fn ,通…

基于ssm+vue的宠物医院系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

GitHub提交 / 拉取时 443 fatal: unable to access ‘https:

这个问题嘛 懂得都懂 但是用了魔法后依旧会出现443错误 排查了工具发现并不是工具的问题 修改一下git代理即可解决 解决方法如下 确保魔法可用的情况下 打开魔法 打开系统设置 > 网络和Internet > 代理 找到自己的代理IP 如下 这里以我的代理IP和端口举例 在…

js变量提升

js变量提升 在JavaScript中,变量提升(Hoisting)是一种特殊的语法行为,它允许变量和函数声明在它们实际出现之前被JavaScript引擎识别。这意味着,当你在代码的后面部分使用一个变量或函数时,JavaScript引擎…

【每日一题】2788. 按分隔符拆分字符串-2024.1.20

题目: 2788. 按分隔符拆分字符串 给你一个字符串数组 words 和一个字符 separator ,请你按 separator 拆分 words 中的每个字符串。 返回一个由拆分后的新字符串组成的字符串数组,不包括空字符串 。 注意 separator 用于决定拆分发生的位…

六个顶级的Python可视化项目

如果你是Python可视化的新手,一些流行的可视化库包括Matplotlib、Seaborn、Plotly、Bokeh、Altair和Folium,以及大量的库和例子可能会让你感到不知所措。 当可视化一个DataFrame时,选择使用哪个可视化库确实是一个头疼的事情。 这篇文章云朵…

输出一个水仙花数

思路: 1.对当前数字i,进行拆解 2.获得百位、十位、个位 3.判断每位立方之和是否等于原数字i package com.ztt.Demo02Exercise;public class test04 {/** 水仙花数*/public static void main(String[] args) {daffodilNumber();}public static void daffo…

pyqt5写一个图形化的文本处理软件

参考资料https://www.zhihu.com/column/pyqt5 最终效果软件 导入安装包 pip install PyQt5 -i https://pypi.douban.com/simple pip install PyQt5-tools -i https://pypi.douban.com/simple要使用PyQt5编写一个文本处理程序,你可以按照以下步骤进行&#xff1a…

【C语言】linux内核ipoib模块 - ipoib_send

一、ipoib_send函数定义 int ipoib_send(struct net_device *dev, struct sk_buff *skb,struct ib_ah *address, u32 dqpn) {struct ipoib_dev_priv *priv ipoib_priv(dev);struct ipoib_tx_buf *tx_req;int hlen, rc;void *phead;unsigned int usable_sge priv->max_sen…

图片验证码+短信验证码

图片验证码短信验证码 图片验证码短信验证码 图片验证码 在调用接口的时候,只要触发了这个接口,就要换验证码(无论成功与否) if (!redisDao.deleteKey(phKey)) {throw new CustomException("验证码错误");}短信验证码 在短信验证的时候&…

基于python socket实现TCP/UDP通信

两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中…

Kotlin 同步与异步执行:run、runCatching、runBlocking 与 runInterruptible

前言 首先,run 和 runCatching 是同步的,而 runBlocking 和 runInterruptible 是异步的。 run 和 runCatching 是 Kotlin 标准库的一部分,可以在所有支持的平台上使用。 runBlocking 和 runInterruptible 是 Coroutines 的一部分。 一、run…

使用 crypto-js 进行 AES 加解密操作

在前端开发中,数据的加密和解密是为了保障用户隐私和数据的安全性而常见的任务。AES(Advanced Encryption Standard)是一种对称密钥加密算法,被广泛用于保护敏感信息的传输和存储。本文将介绍 AES 加解密的基本原理,并…

寒假思维训练计划day11

每日一题,这两天有事,断更了一天,今天补上,感觉状态也不太好,来道1500的题压压惊。 宣传一下我总结的几个构造题模型,一点个人的浅薄见解: 1、前后缀贪心,比如说观察前后缀的sum&…

解决el-radio-group只触发一次的问题

1.需求是点击合并后&#xff0c;出来二次确认框。现在的问题是点击完出现二次确认框后&#xff0c;再次点击不出来二次确认框了 2.一开始代码是这样写的 <el-radio-group v-model"unfold" size"mini" changechangeMerge><el-radio-button :labe…

RK3568平台 LT9211转接芯片调试笔记

一.简介 龙讯LT9211是一个高性能转换器&#xff0c;支持MIPI LVDS TTL两两之间转换。 使用此款芯片大部分为MIPI与LVDS进行互相转换。 下图为LT9211的典型应用图&#xff1a; 二.LT9211原理图 三.车载显示器和摄像头系统 四.调试LT9211输出 MIPI数据 &#xff08;1&#xf…