【问题标题】:Can I use scalable pixels for layout dimensions?我可以将可缩放像素用于布局尺寸吗?
【发布时间】:2021-02-26 18:06:44
【问题描述】:

有人知道使用sp 单位作为布局尺寸有什么问题吗?那么,假设我有一个16sp 文本,例如将TextView 高度设置为20sp 是否有任何问题,所以它会随文本缩放?

<TextView
    android:textSize="16sp"
    android:layout_width="match_parent"
    android:layout_height="20sp"
    ...

这样,文本周围的填充在缩放后与文本大小保持成比例。此外,这对于自动调整大小很有用,不建议使用 wrap_content

然而,official docs 声明 sp 不应该用于文本大小(尽管没有任何解释):

但是,在定义文本大小时,您应该改用可缩放 像素 (sp) 作为单位(但从不使用 sp 作为布局大小)。

这背后的原因是什么? dps 和sps 最终都会转换为特定设备的像素量,不是吗?那么核心区别是什么?

【问题讨论】:

    标签: android android-layout android-xml android-xml-attribute


    【解决方案1】:

    来自文档:https://developer.android.com/training/multiscreen/screendensities

    要在不同密度的屏幕上保持 UI 的可见尺寸,您必须使用与密度无关的像素 (dp) 作为度量单位来设计 UI。一 dp 是一个虚拟像素单位,大致等于中等密度屏幕(160dpi;“基线”密度)上的一个像素。

    所以,dp 的整个想法是指定一个独立于屏幕密度的度量。

    但是,在定义文本大小时,您应该使用可缩放像素 (sp) 作为单位(但不要使用 sp 作为布局大小)。默认情况下,sp 单位的大小与 dp 相同,但它会根据用户喜欢的文本大小调整大小。

    这里的想法是,如果用户有视力障碍,他可以通过更改系统设置来更改文本的大小。另请注意 sp 单位与 dp 大小相同:在系统设置为默认文本大小的情况下,dp 和 sp 之间没有区别。所以你不应该看到在 sp 和 dp 之间改变你的布局大小有什么不同。两者都将转换为相同数量的像素。

    但从不使用 sp 作为布局尺寸的原因仅仅是您不希望图像、按钮或任何其他布局尺寸根据文本大小的系统偏好进行缩放。这对我来说似乎很明显。

    辅助功能设置:https://support.google.com/accessibility/android/answer/6006972

    Android OS 上将不同单位转换为像素的代码是:(来自https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/util/TypedValue.java

        public static float applyDimension(int unit, float value,
                                           DisplayMetrics metrics)
        {
            switch (unit) {
            case COMPLEX_UNIT_PX:
                return value;
            case COMPLEX_UNIT_DIP:
                return value * metrics.density;
            case COMPLEX_UNIT_SP:
                return value * metrics.scaledDensity;
            case COMPLEX_UNIT_PT:
                return value * metrics.xdpi * (1.0f/72);
            case COMPLEX_UNIT_IN:
                return value * metrics.xdpi;
            case COMPLEX_UNIT_MM:
                return value * metrics.xdpi * (1.0f/25.4f);
            }
            return 0;
        }
    

    以及解释什么是 scaledDensity 的评论:(来自https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/DisplayMetrics.java

        /**
         * A scaling factor for fonts displayed on the display.  This is the same
         * as {@link #density}, except that it may be adjusted in smaller
         * increments at runtime based on a user preference for the font size.
         */
        public float scaledDensity;
    

    【讨论】:

    • 永远不要说永远 :) 为什么不呢?是的,如果用户更改文本大小并且您没有考虑到这种可能性,您的布局可能会变得一团糟。但是如果你这样做,你可以帮助你的视障用户更清楚地看到你的布局的一些小细节。此外,我怀疑如果仅在字符串上而不是在按钮上使用 sp 单位,那么一个固定大小的小按钮几乎不会比其中的字符串大。我错了吗?
    • @x00 是的,我同意你的观点,在某些情况下这可能是一个不错的解决方法。
    • 基本上,我只是想知道将sp 用于布局尺寸是否有可能会产生一些意想不到的后果,例如布局在某些 Android 版本等上完全被破坏。我完全可以确保布局适合每个特定的字体大小设置。
    • 基于此:case COMPLEX_UNIT_SP: return value * metrics.scaledDensity;,看起来它只是应用一个乘数并返回一个数字,所以应该没问题。
    【解决方案2】:

    在我看来,如果我错了,我认为任何人都可以使用两者来纠正我,因为我还在学习。现在回到答案

    区别在于dp是固定单位,sp会根据手机字体大小设置进行缩放。

    这是一个例子

    带有 SPDP

    的文本

    更改设备文本设置(Settings -&gt; Display -&gt; Font Size)

    现在重新打开应用程序并重新查看文本,您会看到使用 SP 的文本与 DP 的高度不同。

    【讨论】:

    • 问题是关于布局尺寸,例如宽度、内边距等。文字大小相当简单。
    • Usama,抱歉,没听懂
    猜你喜欢
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 2010-11-29
    相关资源
    最近更新 更多