得到ImageView中drawable显示的区域的计算方法
我们都知道Imageview中有不同的拉伸比率,比如fitStart,centCrop这样的,所以imageview中的drawable不一定和imageview占有相同的位置和大小,那么怎么计算呢?
思路:
1.得到imageview现在的宽高
2.得到imageview现在显示的区域(Rect)
3.得到drawable本身图片的宽高
4.得到drawable显示时的缩放比例
5.计算得到drawable现在显示的宽高
6.通过drawable显示的宽高和imageview显示的宽高来计算出imageview距离内部drawable的内边距
7.通过imageview的显示区域和內边距计算出drawable的显示区域
// view的实际宽高 float vWidth = v.getWidth(); float vHeight = v.getHeight(); // 得到imageview中的矩阵,准备得到drawable的拉伸比率 Matrix m = v.getImageMatrix(); float[] values = new float[10]; m.getValues(values); // drawable的本身宽高 float dOriginalWidth = drawable.getIntrinsicWidth(); float dOriginalHeight = drawable.getIntrinsicHeight(); float dRatio = dOriginalWidth / dOriginalHeight;//如果大于1,表示drawable宽>高 drawable = null; //Image在绘制过程中的变换矩阵,从中获得x和y方向的缩放系数 value[0],[4] //得到drawable的实际显示时的宽高 int dWidth = (int)(dOriginalWidth * values[0]); int dHeight = (int)(dOriginalHeight * values[4]); //得到imageview的宽高和drawable的宽高的差值 float w = vWidth - dWidth; float h = vHeight - dHeight; Rect startBounds = new Rect(); v.getGlobalVisibleRect(startBounds);
之后通过对startBounds进行修改,就可以求出drawable实际显示的范围了。因为拉伸模式不同,所以计算方式也不同,下面给出几种模式的计算方式
if (originalType == ScaleType.CENTER_INSIDE) { //finalBounds = getCentInside_originalPic_finalBounds(v, dRatio, startBounds); finalBounds.left = (int) (startBounds.left + (w / 2) + 0.5f); finalBounds.top = (int) (startBounds.top + (h / 2) +0.5f); finalBounds.right = (int) (startBounds.right - (w / 2) + 0.5f); finalBounds.bottom = (int) (startBounds.bottom - (h / 2) + 0.5f); } else if (originalType == ScaleType.FIT_START) { //finalBounds = getFitStart_originalPic_finalBounds(dRatio, startBounds); finalBounds.right = (int) (startBounds.right - w + 0.5f); finalBounds.top = startBounds.top; finalBounds.left = startBounds.left; finalBounds.bottom = (int) (startBounds.bottom - h + 0.5f); } else if (originalType == ScaleType.FIT_CENTER) { //finalBounds = getFitCenter_originalPic_finalBounds(dRatio, startBounds); finalBounds.left = (int) (startBounds.left + (w / 2) + 0.5f); finalBounds.top = (int) (startBounds.top + (h / 2) +0.5f); finalBounds.right = (int) (startBounds.right - (w / 2) + 0.5f); finalBounds.bottom = (int) (startBounds.bottom - (h / 2) + 0.5f); } else if (originalType == ScaleType.FIT_END) { //finalBounds = getFitEnd_originalPic_finalBounds(dRatio, startBounds); finalBounds.left = (int) (startBounds.left + w + 0.5f); finalBounds.top = (int) (startBounds.top + h + 0.5f); finalBounds.right = startBounds.right; finalBounds.bottom = startBounds.bottom; }
参考自:http://blog.csdn.net/liu_zhen_wei/article/details/8349400
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?