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。

相关推荐

  1. css接触

    2024-06-08 15:38:03       35 阅读
  2. 表格如何让表格和外边重叠

    2024-06-08 15:38:03       60 阅读
  3. html 内外区别以及解释

    2024-06-08 15:38:03       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-08 15:38:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-08 15:38:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-08 15:38:03       82 阅读
  4. Python语言-面向对象

    2024-06-08 15:38:03       91 阅读

热门阅读

  1. webrtc客户端测试和arm平台测试(待补充)

    2024-06-08 15:38:03       29 阅读
  2. 用r语言处理 Excel数据当中的缺失值方法

    2024-06-08 15:38:03       33 阅读
  3. 【Unity】资源管理与热更 YooAsset+HybridCLR

    2024-06-08 15:38:03       36 阅读
  4. 0101__linux libtool简单使用

    2024-06-08 15:38:03       31 阅读
  5. 05 Linux 内核启动流程

    2024-06-08 15:38:03       28 阅读
  6. 【GIC400】——中断使能

    2024-06-08 15:38:03       31 阅读
  7. VMware给没安装VMTools的系统封装ISO以送入文件

    2024-06-08 15:38:03       27 阅读
  8. 安全区域边界

    2024-06-08 15:38:03       30 阅读