您的位置:首页 > 健康 > 养生 > Android RelativeLayout Rtl布局下的bug:paddingStart会同时作用于左右内边距

Android RelativeLayout Rtl布局下的bug:paddingStart会同时作用于左右内边距

2025/3/10 15:07:30 来源:https://blog.csdn.net/qq_23129309/article/details/139456209  浏览:    关键词:Android RelativeLayout Rtl布局下的bug:paddingStart会同时作用于左右内边距

问题现象

问题示例
如上图,只是设置了paddingStart,在RTL布局下,左右都产生了10dp的间距。其他布局如LinearLayout,FrameLayout则没有这个问题。

    private void positionAtEdge(View child, LayoutParams params, int myWidth) {if (isLayoutRtl()) {// myWidth是RelativeLayout宽度(父View指定的,不是最终宽度),params.mRight是子View位置。//这里可以看出计算时已经减去了mPaddingRight(RTL布局下mPaddingRight 就是PaddingStart)// 所以这个mLeft是考虑了右边距的。params.mRight = myWidth - mPaddingRight - params.rightMargin;params.mLeft = params.mRight - child.getMeasuredWidth();} else {params.mLeft = mPaddingLeft + params.leftMargin;params.mRight = params.mLeft + child.getMeasuredWidth();}}
...if (isWrapContentWidth) {if (isLayoutRtl()) {if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {width = Math.max(width, myWidth - params.mLeft);} else {// 这个width最终会参与RelativeLayout的宽度计算,这里也是包含了右边的padding的。width = Math.max(width, myWidth - params.mLeft + params.leftMargin);}} else {if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {width = Math.max(width, params.mRight);} else {width = Math.max(width, params.mRight + params.rightMargin);}}
}...
if (isWrapContentWidth) {// Width already has left padding in it since it was calculated by looking at// the right of each child view// 重点是这里,上面计算的width在问题场景已经包含了右内边距,// 这里又加了一次。所以最终边距是双份的。// 从注释也能看出,原生没有考虑这种情况。width += mPaddingRight;if (mLayoutParams != null && mLayoutParams.width >= 0) {width = Math.max(width, mLayoutParams.width);}

总结:原生在进行测量时没有考虑这种情况,在计算RelativeLayout布局宽度时多加了一个paddStart,但child的位置计算(layout)并未受到影响,所以最终效果类似于既指定了paddStart又指定了paddingEnd。

解决方法

1.使用其他布局,如线性布局,帧布局,约束布局等替换。
2.使用marginStart替代paddingStart实现相同的UX效果。

问题原因

经过分析源码发现这是RelativeLayout测量布局的一个bug。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com