#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;
, похоже, что он просто применяет множитель и возвращает число, так что все должно быть в порядке.