Android中用ScaleGestureDetector缩放View后,能否获取可见区域的Rect?
可以通过Rect获取缩放后内容的可见区域
当然能拿到你说的绿色区域(缩放后内容的可见部分),核心思路是计算View的显示边界和缩放后完整内容区域的交集,具体步骤和实现如下:
关键前提
你需要维护几个核心变量:
- 内容的原始宽高(
originalContentWidth、originalContentHeight) - 当前的缩放因子(
scaleFactor,即你通过ScaleGestureDetector得到的缩放值) - 内容相对于View的偏移量(
offsetX、offsetY,如果支持拖动平移,需要记录这个值)
实现步骤
1. 获取View的可见显示区域
用getLocalVisibleRect(Rect)方法获取View在自身坐标系下的可见范围(对应你说的黑色屏幕区域):
Rect viewVisibleRect = new Rect(); getLocalVisibleRect(viewVisibleRect);
2. 计算缩放后内容的完整区域
结合原始尺寸、缩放因子和偏移量,构建缩放后内容的完整Rect:
Rect contentFullRect = new Rect( (int) offsetX, (int) offsetY, (int) (offsetX + originalContentWidth * scaleFactor), (int) (offsetY + originalContentHeight * scaleFactor) );
3. 计算交集得到可见区域
通过Rect.setIntersect()方法计算两个区域的交集,结果就是你要的绿色区域:
Rect visibleContentRect = new Rect(); // 如果两个区域有交集,visibleContentRect会被设置为交集区域,返回true if (visibleContentRect.setIntersect(viewVisibleRect, contentFullRect)) { // 这里的visibleContentRect就是缩放后内容的可见部分 }
进阶:用矩阵处理复杂变换
如果你的自定义View是通过Canvas的变换矩阵来实现缩放/平移的(比如canvas.scale()、canvas.translate()),可以直接用矩阵来计算内容区域,更准确:
// 假设这是你应用在Canvas上的变换矩阵 Matrix transformMatrix = new Matrix(); transformMatrix.postScale(scaleFactor, scaleFactor, pivotX, pivotY); // 带中心点的缩放 transformMatrix.postTranslate(offsetX, offsetY); // 原始内容的Rect RectF originalRect = new RectF(0, 0, originalContentWidth, originalContentHeight); // 应用矩阵得到缩放后的内容Rect RectF scaledContentRect = new RectF(); transformMatrix.mapRect(scaledContentRect); // View的可见区域转成RectF Rect viewVisibleRect = new Rect(); getLocalVisibleRect(viewVisibleRect); RectF viewVisibleRectF = new RectF(viewVisibleRect); // 计算交集 RectF visibleContentRectF = new RectF(); if (visibleContentRectF.setIntersect(viewVisibleRectF, scaledContentRect)) { // 转成整数Rect(如果需要) Rect visibleContentRect = new Rect(); visibleContentRectF.round(visibleContentRect); }
内容的提问来源于stack exchange,提问作者user1865027
相关产品推荐
相关产品推荐

