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

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

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

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

2.7QVGA 30sp

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

7in WSVGA 30sp

Я попытался использовать оба "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"/>

12 ответов

Решение

@forcelain Я думаю, вам нужно проверить этот Google IO Pdf для дизайна. В этом PDF-файле перейдите на страницу № 77, на которой вы найдете информацию о том, как предлагать использовать размер s.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, начиная с Android 3.2, small, normal, large и xlarge устарели, в пользу следующего:

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

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

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

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

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

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

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

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

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

Примеры: sw600dp sw720dp

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

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

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

Это альтернатива обобщенным квалификаторам размера экрана (маленький, нормальный, большой, большой), которые позволяют вам определять дискретное число для эффективного размера, доступного для вашего пользовательского интерфейса. Использование наименьшей ширины для определения общего размера экрана полезно, потому что ширина часто является движущим фактором при разработке макета. Пользовательский интерфейс часто прокручивается по вертикали, но имеет довольно жесткие ограничения на минимальное пространство, необходимое ему по горизонтали. Доступная ширина также является ключевым фактором при определении того, использовать ли макет с одной панелью для мобильных телефонов или макет с несколькими панелями для планшетов. Таким образом, вы, вероятно, больше всего заботитесь о том, какая минимально возможная ширина будет на каждом устройстве. Доступная ширина экрана 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, ваше приложение может переключаться между различными ресурсами макета для мобильных телефонов и планшетов, используя любое число, необходимое для ширины и / или высоты. Например, если 600dp - это наименьшая доступная ширина, поддерживаемая макетом планшета, вы можете предоставить следующие два набора макетов:

res / layout / main_activity.xml # Для мобильных телефонов res/layout-sw600dp/main_activity.xml # Для планшетов

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

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

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

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

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

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

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

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

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

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

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

Теперь внутри файла измерения.xml вы должны разместить размеры текста. Я показываю вам код для значений-hdpi, аналогично, вы должны разместить код для файла других значений values ​​/ dimensions.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. HDP: 12 пикселей
  2. xhdpi: 18 пикселей
  3. xxhdpi: 24 пикс.
  4. XXXHDPI: 36 пикселей

Это простое решение для реализации необходимого размера текста для всех разрешений. Я не рассматриваю здесь устройства с разрешением mdpi. Если кто-то хочет включить размер текста для этого разрешения, то соотношение составляет 3: 4: 6: 8: 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"/>

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

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

https://github.com/intuit/sdp

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

XML:

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

Код:

   Paint p =new Paint();
       p.setTextSize(getResources().getDimension(R.dimen.text_Size));

Я знаю, что уже поздно, но это может помочь кому-то...

      <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:autoSizeTextType="uniform"
        android:gravity="center_horizontal|bottom"
        android:text="Your text goes here!"
        android:layout_centerInParent="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.05"
        app:layout_constraintHorizontal_bias="0.50"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.50"
        app:layout_constraintWidth_percent="0.50" />
</androidx.constraintlayout.widget.ConstraintLayout>

Кроме того, если вы хотите настроить размер текста, попробуйте изменить

      app:layout_constraintWidth_percent="0.50" 
app:layout_constraintHeight_percent="0.05"

Это все.

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

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

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

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

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

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

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

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

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

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

<Button
  app:autoSizeTextType="uniform" />

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

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

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

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

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

Для обеспечения гибкости и новых разрешений экрана лучше всего разместить фиктивный 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 в качестве ссылки, к которой вы можете добавить константу или размер в процентах (путем расчета).

Как упомянуто в @espinchi из 3.2 (уровень API 13), размерные группы устарели. Диапазон размеров экрана является предпочтительным подходом в будущем.

Другие вопросы по тегам