使用ScaleType.CENTER的AppCompatImageView加载大图时padding设置疑问
原因解答
ScaleType.CENTER的核心规则是不对原图做缩放,将原图的中心点和ImageView内容区域的中心点对齐绘制,超出View边界的部分直接裁剪。- 系统计算绘制偏移时,会先把ImageView的padding值扣除,得到内容可用区域,再基于可用区域计算居中偏移量。
偏移计算公式推导
我们定义几个变量方便计算:
- 原图宽度:
w_src = 3264,原图高度:h_src = 1836 - ImageView宽度:
w_view = 1280,ImageView高度:h_view =720 - 宽差:
Δw = w_src - w_view = 1984,高差:Δh = h_src - h_view = 1116 - 你设置的左内边距
paddingLeft,上内边距paddingTop,右和下内边距为0
默认无padding的情况
当你不设置任何padding时,内容可用区域和View大小一致,系统计算的绘制偏移为:
- 水平偏移:
(w_view - w_src)/2 = -Δw/2(负号代表往x轴负方向偏移,也就是图片左边被裁掉Δw/2) - 垂直偏移:
(h_view - h_src)/2 = -Δh/2(同理图片上边被裁掉Δh/2)
这时候图片是居中展示的,左上角坐标为(-Δw/2, -Δh/2),这就是你以为偏移Δ/2就能拉回原点的认知来源,只对了一半,因为你没考虑padding对可用区域的影响。
你设置padding后的计算
ScaleType.CENTER的最终绘制偏移公式为:
最终水平偏移 =
paddingLeft + (可用宽度 - w_src)/2
最终垂直偏移 =paddingTop + (可用高度 - h_src)/2
其中 可用宽度 =w_view - paddingLeft - paddingRight,可用高度 =h_view - paddingTop - paddingBottom
你的目标是最终偏移为0,也就是左上角对齐View的(0,0),代入公式求解paddingLeft:
0 = paddingLeft + [(w_view - paddingLeft) - w_src]/2 两边乘2:0 = 2*paddingLeft + w_view - paddingLeft - w_src 合并:0 = paddingLeft + w_view - w_src 得:paddingLeft = w_src - w_view = Δw
垂直方向同理可得paddingTop = Δh,和你实际测试的结果完全一致。
为什么你以为要除以2?
你的误区是忽略了ScaleType.CENTER自带的居中偏移逻辑:
- 如果你只设置
paddingLeft = Δw/2,代入公式得到的最终水平偏移是Δw/2 + (w_view - Δw/2 -w_src)/2 = -Δw/4,图片左上角依然在负坐标位置,没有对齐到原点。 - 只有设置
paddingLeft = Δw,才能刚好抵消ScaleType.CENTER默认的负偏移,让最终绘制的起始点刚好落在(0,0)。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

