Могу ли я использовать масштабируемые пиксели для размеров макета?

#android #android-layout #android-xml #android-xml-attribute

#Android #android-layout #android-xml #android-xml-attribute

Вопрос:

Кто-нибудь знает о каких-либо проблемах с использованием sp единиц измерения для размеров макета? Итак, допустим, у меня есть 16sp текст, есть ли какие-либо проблемы с установкой TextView высоты 20sp , например, чтобы она масштабировалась вместе с текстом?

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

Таким образом, отступы вокруг текста остаются пропорциональными размеру текста после масштабирования. Кроме того, это полезно при автоматическом определении размера, где использование wrap_content не рекомендуется.

Однако в официальных документах указано, что sp это никогда не должно использоваться для размера текста (хотя и без каких-либо объяснений):

Однако при определении размеров текста в качестве единиц измерения следует использовать масштабируемые пиксели (sp) (но никогда не используйте sp для размеров макета).).

В чем причина этого? И dp s, и sp s в конечном итоге преобразуются в определенное количество пикселей, зависящее от устройства, не так ли? В чем тогда основная разница?

Ответ №1:

Из документации: https://developer.android.com/training/multiscreen/screendensities

Чтобы сохранить видимый размер вашего пользовательского интерфейса на экранах с разной плотностью, вы должны спроектировать свой пользовательский интерфейс, используя в качестве единицы измерения пиксели, не зависящие от плотности (dp). Один dp — это виртуальная пиксельная единица, которая примерно равна одному пикселю на экране средней плотности (160 точек на дюйм; «базовая» плотность).

Итак, вся идея dp заключается в том, чтобы указать меру, которая не зависит от плотности экрана.

Однако при определении размеров текста вместо этого следует использовать масштабируемые пиксели (sp) в качестве единиц измерения (но никогда не используйте sp для размеров макета). По умолчанию единица измерения sp имеет тот же размер, что и dp, но ее размер изменяется в зависимости от предпочтительного размера текста пользователя.

Здесь идея заключается в том, что если пользователь слабовидящий, он может изменить размер текста, изменив системные настройки. Также обратите внимание, что единица измерения sp имеет тот же размер, что и dp: при системной настройке размера текста по умолчанию между dp и sp нет разницы. Таким образом, вы не должны видеть никакой разницы в изменении размера макета между sp и dp. оба будут преобразованы в одинаковое количество пикселей.

Причина, по которой вы никогда не используете sp для размеров макета, заключается просто в том, что вы не хотите, чтобы изображения, кнопки или любые другие размеры макета масштабировались в зависимости от системных предпочтений размера текста. Мне это кажется довольно очевидным.

Настройки специальных возможностей: https://support.google.com/accessibility/android/answer/6006972

код в ОС Android, который преобразует разные единицы измерения в пиксели: (из 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;
 

Комментарии:

1. Никогда не говори никогда 🙂 Почему бы и нет? Да, ваш макет может стать беспорядочным, если пользователь изменит размер текста, а вы не учитываете эту возможность. Но если вы это сделаете, вы можете помочь пользователям с ослабленным зрением более четко видеть некоторые мелкие детали вашего макета. Также я подозреваю, что небольшая кнопка фиксированного размера, едва превышающая строку в ней, не выиграет от sp единиц измерения, если они используются только в строке, но не на кнопке. Я ошибаюсь?

2. @x00 да, я согласен с вами, что в некоторых случаях это может быть хорошим обходным путем.

3. По сути, я просто хочу знать, есть ли вероятность, что будут какие-то неожиданные последствия использования sp для размеров макета, например, макет становится полностью нарушенным в какой-то версии Android и т. Д. Я полностью согласен с тем, чтобы макет выглядел хорошо для каждого конкретного параметра размера шрифта.

4. Исходя из этого: case COMPLEX_UNIT_SP: return value * metrics.scaledDensity; , похоже, что он просто применяет множитель и возвращает число, так что все должно быть в порядке.