当前位置: 首页 > news >正文

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

 

相关文章:

  • 回溯法:N皇后问题
  • 【PGSQL】date_trunc 函数
  • 【导航】繁星学习随想录
  • 了解Vue中日历插件Fullcalendar
  • Elasticsearch 分布式架构剖析及扩展性优化
  • 初识计算机图形学
  • openssl3.2 - 官方demo学习 - mac - poly1305.c
  • CSS 设置背景图片
  • 【JavaEE】网络原理:网络中的一些基本概念
  • AI+量化02_金融市场的基础概念
  • 蓝桥oj3272小蓝的漆房
  • 【SpringCloud】微服务框架后端部署详细过程记录20240119
  • Unity - transform使用
  • C++核心编程
  • unity webgl 系列(2):从webgl内存中下载文件到本地硬盘
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • HTTP中的ETag在移动客户端的应用
  • React-Native - 收藏集 - 掘金
  • springMvc学习笔记(2)
  • ubuntu 下nginx安装 并支持https协议
  • Zsh 开发指南(第十四篇 文件读写)
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 对象引论
  • - 概述 - 《设计模式(极简c++版)》
  • 码农张的Bug人生 - 初来乍到
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 前端路由实现-history
  • 一些关于Rust在2019年的思考
  • 函数计算新功能-----支持C#函数
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • # Java NIO(一)FileChannel
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • #在 README.md 中生成项目目录结构
  • (2.2w字)前端单元测试之Jest详解篇
  • (done) 两个矩阵 “相似” 是什么意思?
  • (pytorch进阶之路)扩散概率模型
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (七)Java对象在Hibernate持久化层的状态
  • (十六)Flask之蓝图
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)大型网站的系统架构
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .bat批处理(一):@echo off
  • .describe() python_Python-Win32com-Excel
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET Core 中的路径问题
  • .NET 回调、接口回调、 委托
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET6实现破解Modbus poll点表配置文件
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • /run/containerd/containerd.sock connect: connection refused