Размер текста и разные размеры экрана Android

121

Я знаю, это обсуждалось уже 1000 раз, но я не могу настроить размер текста под разные размеры экрана. Я пытаюсь использовать sp в качестве единиц размера в своем индивидуальном стиле:

<style name="CustumButtonStyle" parent="@android:style/Widget.Button">
    ...
    <item name="android:textSize">30sp</item>
    ...
</style>

В 2.7 QVGA выглядит нормально:

2.7QVGA, 30 скоростей

Но в 7in WSVGA это выглядит так:

7 дюймов, WSVGA, 30 скоростей

Я пробовал использовать и sp, и dp с тем же результатом.

Не могли бы вы объяснить, как сделать так, чтобы эти кнопки выглядели одинаково на любом экране?

Полный пользовательский стиль кнопки

<style name="CustumButtonStyle" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/custom_button</item>
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_margin">3dp</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:gravity">center</item>
    <item name="android:textSize">30sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:shadowColor">#000000</item>
    <item name="android:shadowDx">1</item>
    <item name="android:shadowDy">1</item>
    <item name="android:shadowRadius">2</item>
</style>

И в моей теме приложения у меня есть

<item name="android:buttonStyle">@style/CustumButtonStyle</item>

А вот мой макет:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:background="@drawable/grid"
android:gravity="center"
android:orientation="vertical" android:layout_height="fill_parent">

<Button
    android:id="@+id/buttonContinue"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/continue_game" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>



<Button
    android:id="@+id/buttonNewGame"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/buttonContinue"
    android:layout_alignRight="@+id/buttonContinue"
    android:layout_below="@+id/buttonContinue"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/new_game" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>



<Button
    android:id="@+id/ButtonAbout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/buttonNewGame"
    android:layout_alignRight="@+id/buttonNewGame"
    android:layout_below="@+id/buttonNewGame"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/about" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>

forcelain
источник
На ваших экранах они выглядят одинаково. Убедитесь, что ваш зрительский масштаб равен 100%
Дмитрий Зайцев
вы можете найти ответ здесь stackoverflow.com/questions/16706076/…
Бхавеш Джетани

Ответы:

160

@forcelain Я думаю, вам нужно проверить этот Google IO Pdf для дизайна . В этом PDF-файле перейдите на страницу №: 77, на которой вы найдете, как предлагается использовать sizes.xml для разных устройств Android, например, см. Структуру ниже:

res/values/dimens.xml

res/values-small/dimens.xml

res/values-normal/dimens.xml

res/values-large/dimens.xml

res/values-xlarge/dimens.xml

Например, в значениях вы использовали размер .xml ниже.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="text_size">18sp</dimen>
</resources>

В папке с другими значениями вам нужно изменить значения для вашего размера текста.

Примечание. Как указано в @espinchi, small, normal, large и xlarge устарели с Android 3.2 в пользу следующего:

Объявление макетов планшета для Android 3.2

Для первого поколения планшетов под управлением Android 3.0 правильным способом объявления макетов планшета было помещение их в каталог с квалификатором конфигурации xlarge (например, res / layout-xlarge /). Для поддержки других типов планшетов и экранов, в частности 7-дюймовых планшетов, в Android 3.2 представлен новый способ указания ресурсов для более дискретных размеров экрана. Новый метод основан на объеме пространства, необходимом для вашего макета (например, 600dp ширины), а не пытаться подогнать макет под общие размерные группы (например, large или xlarge).

Причина, по которой проектирование 7-дюймовых планшетов затруднительно при использовании обобщенных групп размеров, заключается в том, что 7-дюймовый планшет технически находится в той же группе, что и 5-дюймовый телефон (большая группа). В то время как эти два устройства кажутся близкими друг к другу по размеру. объем пространства для пользовательского интерфейса приложения существенно отличается, как и стиль взаимодействия с пользователем. Таким образом, на экранах с диагональю 7 дюймов и 5 дюймов не всегда должна использоваться одна и та же компоновка. Чтобы вы могли использовать разные макеты для этих Два типа экранов, Android теперь позволяет вам указывать ресурсы макета на основе ширины и / или высоты, которые фактически доступны для макета вашего приложения, указанного в единицах dp.

Например, после того, как вы разработали макет, который хотите использовать для устройств в стиле планшета, вы можете определить, что макет перестает работать, когда экран имеет ширину менее 600 dp. Таким образом, этот порог становится минимальным размером, необходимым для макета планшета. Таким образом, теперь вы можете указать, что эти ресурсы макета должны использоваться только тогда, когда для пользовательского интерфейса вашего приложения доступно не менее 600 dp ширины.

Вы должны либо выбрать ширину и создать ее как свой минимальный размер, либо проверить, какую наименьшую ширину поддерживает ваш макет после его завершения.

Примечание: помните, что все цифры, используемые с этими новыми API-интерфейсами размеров, являются значениями пикселей, не зависящими от плотности (dp), и размеры вашего макета также всегда должны определяться с использованием единиц dp, потому что вас интересует количество места на экране, доступное после системы учитывает плотность экрана (в отличие от разрешения сырых пикселей). Дополнительные сведения о пикселях, не зависящих от плотности, см. В разделе «Термины и концепции» ранее в этом документе. Использование квалификаторов нового размера

Различные конфигурации ресурсов, которые вы можете указать в зависимости от пространства, доступного для вашего макета, сведены в таблицу 2. Эти новые квалификаторы предлагают вам больше контроля над конкретными размерами экрана, которые поддерживает ваше приложение, по сравнению с традиционными группами размеров экрана (маленький, нормальный, большой и xlarge).

Примечание. Размеры, которые вы указываете с помощью этих квалификаторов, не являются фактическими размерами экрана. Скорее, размеры указаны для ширины или высоты в единицах dp, которые доступны для окна вашей активности. Система Android может использовать часть экрана для пользовательского интерфейса системы (например, системную строку внизу экрана или строку состояния вверху), поэтому часть экрана может быть недоступна для вашего макета. Таким образом, размеры, которые вы объявляете, должны конкретно соответствовать размерам, необходимым для вашей деятельности - система учитывает любое пространство, используемое пользовательским интерфейсом системы при объявлении, сколько места она предоставляет для вашего макета. Также имейте в виду, что панель действий считается частью оконного пространства вашего приложения, хотя ваш макет не объявляет это, поэтому он уменьшает пространство, доступное для вашего макета, и вы должны учитывать это в своем дизайне.

Таблица 2. Новые квалификаторы конфигурации для размера экрана (введены в Android 3.2). Конфигурация экрана Значения квалификатора Описание smallestWidth swdp

Примеры: sw600dp sw720dp

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

Например, если ваш макет требует, чтобы его наименьший размер области экрана всегда был не менее 600 dp, вы можете использовать этот квалификатор для создания ресурсов макета, res / layout-sw600dp /. Система будет использовать эти ресурсы только тогда, когда наименьший размер доступного экрана составляет не менее 600 dp, независимо от того, является ли сторона 600 dp воспринимаемой пользователем высотой или шириной. Наименьшая ширина - это фиксированный размер экрана, характерный для устройства; smallestWidth устройства не изменяется при изменении ориентации экрана.

Наименьшая ширина устройства учитывает оформление экрана и пользовательский интерфейс системы. Например, если устройство имеет некоторые постоянные элементы пользовательского интерфейса на экране, которые учитывают пространство по оси smallestWidth, система объявляет, что smallestWidth меньше фактического размера экрана, потому что это пиксели экрана, недоступные для вашего пользовательского интерфейса.

Это альтернатива обобщенным квалификаторам размера экрана (small, normal, large, xlarge), которая позволяет вам определять дискретное число для эффективного размера, доступного для вашего пользовательского интерфейса. Использование smallestWidth для определения общего размера экрана полезно, поскольку ширина часто является определяющим фактором при разработке макета. Пользовательский интерфейс часто прокручивается по вертикали, но имеет довольно жесткие ограничения на минимальное пространство, необходимое по горизонтали. Доступная ширина также является ключевым фактором при определении того, использовать ли макет с одной панелью для телефонов или с несколькими панелями для планшетов. Таким образом, вы, вероятно, больше всего заботитесь о том, какая минимально возможная ширина будет на каждом устройстве. Доступная ширина экрана wdp

Примеры: w720dp w1024dp

Определяет минимальную доступную ширину в единицах dp, при которой должны использоваться ресурсы - определяется значением. Соответствующее системное значение ширины изменяется при переключении ориентации экрана с альбомной на портретную, чтобы отразить текущую фактическую ширину, доступную для вашего пользовательского интерфейса.

Это часто бывает полезно, чтобы определить, следует ли использовать многопанельный макет, потому что даже на планшетном устройстве вам часто не понадобится такой же многопанельный макет для портретной ориентации, как и для альбомной. Таким образом, вы можете использовать это, чтобы указать минимальную ширину, необходимую для макета, вместо использования одновременно квалификаторов размера экрана и ориентации. Доступная высота экрана hdp

Примеры: h720dp, h1024dp и т. Д.

Определяет минимальную высоту экрана в единицах dp, при которой должны использоваться ресурсы - определяется значением. Соответствующее системное значение высоты изменяется, когда ориентация экрана переключается с альбомной на портретную, чтобы отразить текущую фактическую высоту, доступную для вашего пользовательского интерфейса.

Использование этого параметра для определения высоты, необходимой для вашего макета, полезно так же, как wdp для определения требуемой ширины, вместо использования квалификаторов размера экрана и ориентации. Однако большинству приложений этот квалификатор не понадобится, учитывая, что пользовательские интерфейсы часто прокручиваются по вертикали и, таким образом, более гибкие в зависимости от доступной высоты, тогда как ширина более жесткая.

Хотя использование этих квалификаторов может показаться более сложным, чем использование групп размеров экрана, на самом деле это должно быть проще, когда вы определите требования для своего пользовательского интерфейса. При разработке пользовательского интерфейса главное, что вас, вероятно, волнует, - это фактический размер, при котором ваше приложение переключается между пользовательским интерфейсом в стиле телефона и пользовательским интерфейсом в стиле планшета, который использует несколько панелей. Точная точка этого переключателя будет зависеть от вашего конкретного дизайна - может быть, вам нужна ширина 720dp для макета вашего планшета, может быть достаточно 600dp, или 480dp, или какое-то число между ними. Используя эти квалификаторы в таблице 2, вы можете контролировать точный размер, при котором изменяется ваш макет.

Дополнительные сведения об этих квалификаторах конфигурации размера см. В документе «Предоставление ресурсов». Примеры конфигурации

Чтобы помочь вам нацелить некоторые из ваших проектов на разные типы устройств, вот несколько цифр для типичной ширины экрана:

320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
480dp: a tweener tablet like the Streak (480x800 mdpi).
600dp: a 7 tablet (600x1024 mdpi).
720dp: a 10 tablet (720x1280 mdpi, 800x1280 mdpi, etc).

Используя квалификаторы размера из таблицы 2, ваше приложение может переключаться между различными ресурсами макета для телефонов и планшетов, используя любое число, которое вы хотите для ширины и / или высоты. Например, если 600 dp - это наименьшая доступная ширина, поддерживаемая макетом вашего планшета, вы можете предоставить эти два набора макетов:

res / layout / main_activity.xml # Для телефонов res / layout-sw600dp / main_activity.xml # Для планшетов

В этом случае минимальная ширина доступного пространства экрана должна составлять 600 dp, чтобы можно было применить макет планшета.

Для других случаев, когда вы хотите дополнительно настроить пользовательский интерфейс, чтобы различать размеры, такие как планшеты с диагональю 7 дюймов и 10 дюймов, вы можете определить дополнительные макеты с наименьшей шириной:

res / layout / main_activity.xml # Для телефонов (доступная ширина меньше 600 dp) res / layout-sw600dp / main_activity.xml # Для 7-дюймовых планшетов (шириной 600 dp и больше) res / layout-sw720dp / main_activity.xml

Для 10-дюймовых планшетов (шириной 720dp и больше)

Обратите внимание, что в предыдущих двух наборах примеров ресурсов используется квалификатор «наименьшая ширина», swdp, который указывает наименьшую из двух сторон экрана, независимо от текущей ориентации устройства. Таким образом, использование swdp - это простой способ указать общий размер экрана, доступный для вашего макета, игнорируя ориентацию экрана.

Однако в некоторых случаях для вашего макета может быть важно именно то, какая ширина или высота доступны в настоящее время. Например, если у вас есть двухпанельный макет с двумя соседними фрагментами, вы можете использовать его всякий раз, когда экран обеспечивает ширину не менее 600 dp, независимо от того, находится ли устройство в альбомной или книжной ориентации. В этом случае ваши ресурсы могут выглядеть так:

res / layout / main_activity.xml # Для мобильных телефонов (доступная ширина менее 600 dp) res / layout-w600dp / main_activity.xml # Multi-pane (любой экран с доступной шириной 600 dp или более)

Обратите внимание, что во втором наборе используется квалификатор «доступная ширина», wdp. Таким образом, одно устройство может фактически использовать оба макета, в зависимости от ориентации экрана (если доступная ширина составляет не менее 600 dp в одной ориентации и менее 600 dp в другой ориентации).

Если вас беспокоит доступная высота, вы можете сделать то же самое, используя квалификатор hdp. Или даже комбинируйте квалификаторы wdp и hdp, если вам нужно быть действительно конкретным.

Herry
источник
7
Эти small / normal / large / xlarge в настоящее время устарели (декабрь 2014 г.). Теперь предпочтительнее использовать "swxxxdp". См developer.android.com/guide/practices/...
espinchi
1
@espinchi спасибо, вы должны опубликовать это также в качестве ответа. Есть ли также рекомендуемые dp? например стандарты: 100sw, 200sw, 400sw, 600sw.
Винс В.
19

Думаю, уже слишком поздно отвечать в этой ветке. Но я хотел бы поделиться своей идеей или способом решения проблемы с размером текста на устройствах с разностным разрешением. Многие сайты разработчиков Android предлагают использовать sp unit для размера текста, который будет обрабатывать размер текста для устройств с разностным разрешением. Но я всегда не могу добиться желаемого результата. Итак, я нашел одно решение, которое использую из своих последних 4-5 проектов, и оно отлично работает. Согласно моему предложению, вы должны указать размер текста для каждого устройства разрешения, что немного утомительно, но оно удовлетворит ваши требования. Каждый разработчик должен знать о соотношении 4: 6: 8: 12 (h: xh: xxh: xxxh соответственно) . Теперь внутри папки res вашего проекта вам нужно создать 4 папки с размером файла, например.

  1. RES / значение-ИПЧР / dimens.xml
  2. RES / значения-xhdpi / dimens.xml
  3. RES / значения-xxhdpi / dimens.xml
  4. RES / значения-xxxhdpi / dimens.xml

Теперь внутри файла sizes.xml вы должны разместить размеры текста. Я показываю вам код для values-hdpi , аналогично вам нужно разместить код для других значений разрешения / файла sizes.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="text_size">4px</dimen>
</resources>

Для других разрешений это похоже на xhdpi : 6px, xxhdpi : 8px, xxxhdpi : 12px. Это рассчитывается с соотношением (3: 4: 6: 8: 12), которое я написал выше. Давайте обсудим другой пример размера текста с указанным выше соотношением. Если вы хотите взять размер текста 12 пикселей в формате hdpi, то в другом разрешении это будет

  1. hdpi: 12 пикселей
  2. xhdpi: 18 пикселей
  3. xxhdpi: 24 пикселя
  4. xxxhdpi: 36 пикселей

Это простое решение для реализации необходимого размера текста для всех разрешений. Я не рассматриваю здесь устройства с разрешением mdpi . Если кто-то хочет включить размер текста для этого разрешения, тогда соотношение будет примерно 3: 4: 6: 8: 12 . По любым вопросам, пожалуйста, дайте мне знать. Надеюсь, это поможет вам, люди.

Рахул Шарма
источник
4
Разве не плохая практика использовать пиксель вместо sp в размере текста? Есть ли способ добиться следующего соотношения, используя sp вместо px?
Red M
Я проверил, что это работает нормально, но я все еще не понимаю, лучше ли использовать значения в px вместо dp / sp? Я никогда не видел где-нибудь в официальной документации, чтобы использовать значения в пикселях.
shaby
1
используйте sp для размера шрифта, это закон. Подход, который показал Рахул, правильный, просто используйте sp вместо px.
Mihir Patel
sp следует использовать, если вы планируете связать размер шрифта приложения с размером системного шрифта. В противном случае это решение неплохое.
Ирфан Уль Хак,
12

Иногда лучше иметь только три варианта

 style="@android:style/TextAppearance.Small"

Используйте маленький и большой, чтобы отличать экран от обычного размера.

<TextView
            android:id="@+id/TextViewTopBarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@android:style/TextAppearance.Small"/>

В обычном режиме вам не нужно ничего указывать.

<TextView
            android:id="@+id/TextViewTopBarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

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

Калан Наваратне
источник
10

Я сделал то же самое по размеру и нарисовал что-то вроде (с dp, но только для текста и в drawText ())

XML:

   <dimen name="text_size">30sp</dimen>

Код:

   Paint p =new Paint();
       p.setTextSize(getResources().getDimension(R.dimen.text_Size));
Образ жизни
источник
8
Вы НЕ должны использовать dpдля размера текста ... используйте spвместо этого.
Юша Алеайуб
Пожалуйста, используйте sp для размера текста
Thinsky
Вы можете использовать dp в определенных ситуациях, когда вы не хотите, чтобы его размер изменялся в зависимости от предпочтений пользователя.
7

Каждый может использовать указанную ниже библиотеку Android, которая является самым простым способом сделать размеры текста совместимыми практически со всеми экранами устройств. На самом деле он разработан на основе новых квалификаторов конфигурации Android для размера экрана (представленных в Android 3.2) SmallestWidth swdp.

https://github.com/intuit/sdp

Мухаммад Максуд
источник
2
sdp - размер экрана; используйте ssp для размера текста
ecle
Это работает для меня, но я подозреваю, что нужно добавить слишком много файлов, это увеличит размер приложения, @Muhammad, вы можете изменять размер и добавлять только классы по мере необходимости
Киртикумар А.
1

Если у вас есть API 26, вы можете рассмотреть возможность использования autoSizeTextType :

<Button
  app:autoSizeTextType="uniform" />

Настройка по умолчанию позволяет автоматически изменять масштаб TextView по горизонтальной и вертикальной осям.

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview

Бонн Богерт
источник
Проблема в том, что он не меняет размер текста для нескольких текстовых представлений со строками разной длины
равномерно
0

Я думаю, вы можете заархивировать это, добавив несколько ресурсов макета для каждого размера экрана, например:

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size with small text
res/layout-large/my_layout.xml       // layout for large screen size with larger text
res/layout-xlarge/my_layout.xml      // layout for extra large screen size with even larger text
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

Ссылка: 1. http://developer.android.com/guide/practices/screens_support.html

NguyenDat
источник
2
Может быть лучше использовать res / values-small.
Einverne
1
одна из худших реализаций. мы должны поддерживать 5 макетов только для поддержки разных размеров?
SolidSnake
Создание разных макетов для уменьшения размера текста на разных экранах - действительно плохая идея. Не рекомендую
Саман Салехи
0

Чтобы унифицировать все экраны для отображения одинаковых размеров элементов, включая размер шрифта: - Создайте пользовательский интерфейс на одном экране с любыми размерами, которые вы сочтете подходящими во время разработки, например, размер шрифта TextView составляет 14 точек на дюйм при размере экрана по умолчанию с размером экрана 4'6 дюймов.

  • Программно рассчитайте физический размер экрана других телефонов, то есть 5 футов 2 дюйма других телефонов / экранов.

  • Используйте формулу для расчета процентной разницы между двумя экранами. т.е. какая разница между 4'6 и 5'2%.

  • Рассчитайте разницу в пикселях между двумя TextView на основе приведенной выше формулы.

  • Получите фактический размер (в пикселях) TextView font-size и примените разницу в пикселях (рассчитанную ранее) к размеру шрифта по умолчанию.

Таким образом вы можете применить динамическое соотношение сторон ко всем размерам экрана, и результат будет отличным. У вас будет одинаковый макет и размеры на каждом экране.

Сначала это может быть немного сложно, но вы полностью достигнете цели, как только вы разберетесь с формулой. С помощью этого метода вам не нужно создавать несколько макетов только для разных размеров экрана.

Солид Снейк
источник
0

Вы можете также использовать weightSumи layout_weightсвойство корректировать другой экран.

Для этого вы должны сделать android:layout_width= 0dp и android:layout_width= (как хотите);

Harshit
источник
-2

Не указывайте жестко размеры.

Для гибкости и новых разрешений экрана лучше всего поместить фиктивный TextView в макет для получения textSize:

<TextView
        android:id="@+id/dummyTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:text="TextView" />

И в вашем коде, например:

TextView testTextView = (TextView) rootView.findViewById(R.id.dummyTextView);
float textSize = testTextView.getTextSize();

Сохраните textSizeв качестве ссылки, к которой вы можете добавить постоянный размер или размер процента (путем расчета).

Athlan
источник