Розмір тексту та різні розміри екрана для Android


121

Я знаю, це обговорювалося вже 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"/>


На ваших екранах вони виглядають однаково. Переконайтеся, що масштаб вашого глядача становить 100%
Дмитро Зайцев

Ви можете знайти відповідь тут stackoverflow.com/questions/16706076 / ...
Bhavesh Jethani

Відповіді:


160

@forcelain Я думаю, вам потрібно перевірити цей PDF- файл Google IO для дизайну . У цьому PDF-файлі перейдіть на сторінку №: 77, де ви знайдете, як пропонується використовувати dimens.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

для прикладу ви використовували значення dimens.xml у значеннях нижче.

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

В іншій папці значень потрібно змінити значення для розміру тексту.

Примітка. Як зазначає @espinchi, з Android 3.2 застаріле, нормальне, велике та велике розміщення застаріли на користь наступного:

Декларація макетів планшетного ПК для Android 3.2

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

Причина проектування планшетів для 7 "є складною при використанні узагальнених груп розмірів у тому, що 7-дюймовий планшет технічно знаходиться в тій же групі, що і 5-дюймова трубка (велика група). Хоча ці два пристрої, здавалося б, близькі один одному за розмірами , об'єм місця для інтерфейсу програми значно відрізняється, як і стиль взаємодії з користувачем. Таким чином, 7 "і 5" екран не завжди повинен використовувати один і той же макет. Щоб зробити це можливим, ви зможете надати для них різні макети два типи екранів, Android тепер дозволяє вказувати ресурси вашого макета виходячи з ширини та / або висоти, які фактично доступні для макета вашої програми, визначеного в одиницях dp.

Наприклад, після того, як ви розробили макет, який ви хочете використовувати для пристроїв у стилі планшетного ПК, ви можете визначити, що макет перестає працювати добре, коли екран менше 600 дп. Таким чином, цей поріг стає мінімальним розміром, який потрібно для макета планшетного ПК. Відтак тепер ви можете вказати, що ці ресурси макета слід використовувати лише тоді, коли для інтерфейсу вашої програми доступно щонайменше 600dp ширини.

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

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

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

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

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

Приклади: sw600dp sw720dp

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

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

Найменша ширина пристрою враховує декор екрану та системний інтерфейс. Наприклад, якщо пристрій має кілька стійких елементів інтерфейсу на екрані, які займають простір уздовж осі найменшої ширини, система оголошує найменшу ширину меншою, ніж фактичний розмір екрана, оскільки це пікселі екрана, недоступні для вашого інтерфейсу.

Це альтернатива узагальненим класифікаторам розміру екрана (малий, нормальний, великий, великий), що дозволяє визначити дискретне число для ефективного розміру, доступного для вашого інтерфейсу. Використання найменшої ширини для визначення загального розміру екрана корисно, оскільки ширина часто є рушійним фактором при розробці макета. Користувацький інтерфейс часто прокручується вертикально, але має досить жорсткі обмеження щодо мінімального простору, який йому потрібен по горизонталі. Наявна ширина також є ключовим фактором у визначенні того, чи слід використовувати однопанельний макет для телефонів або багатопанельний макет для планшетів. Таким чином, вас, швидше за все, хвилює те, яка найменша ширина буде на кожному пристрої. Доступна ширина екрана 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 # Для планшетів

У цьому випадку найменша ширина наявного екранного простору повинна бути 600 дп, щоб застосовувати макет планшета.

Для інших випадків, коли ви хочете додатково налаштувати свій інтерфейс користувача, щоб розмежувати розміри, такі як 7 ”та 10” планшети, ви можете визначити додаткові макети найменшої ширини:

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

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

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

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

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

Зауважте, що у другому наборі використовується кваліфікатор "доступної ширини", wdp. Таким чином, один пристрій може фактично використовувати обидва макети, залежно від орієнтації екрана (якщо наявна ширина принаймні 600dp в одній орієнтації та менше 600dp в іншій орієнтації).

Якщо доступна висота викликає занепокоєння, ви можете зробити те ж саме, використовуючи hdp-класифікатор. Або навіть комбінуйте кваліфікатори wdp та hdp, якщо вам потрібно бути дійсно конкретними.


7
Ці малі / нормальні / великі / великі на даний момент застарілі (грудень 2014 р.). Зараз кращим способом є використання "swxxxdp". Дивіться developer.android.com/guide/practices/…
espinchi

1
@espinchi спасибі, ви також можете написати це як відповідь. Чи є також рекомендовані dp? наприклад стандарти: 100sw, 200sw, 400sw, 600sw.
Вінс В.

19

Я думаю, що занадто пізно відповісти на цю тему. Але я хотів би поділитися своєю ідеєю чи способом вирішити проблему розміру тексту на пристроях різної роздільної здатності. Багато веб-сайтів розробників для Android пропонують використовувати підрозділ sp для розміру тексту, який буде обробляти розмір тексту для пристроїв різної роздільної здатності. Але я завжди не в змозі отримати бажаний результат. Тож я знайшов одне рішення, яке я використовую з моїх останніх 4-5 проектів, і це прекрасно працює. Згідно з моєю пропозицією, ви повинні розміщувати розмір тексту для кожного пристрою роздільної здатності, що трохи копітка робота, але він виконає вашу вимогу. Кожен розробник повинен слухати про співвідношення, наприклад, 4: 6: 8: 12 (h: xh: xxh: xxxh відповідно) . Тепер у папці Res Resource проекту потрібно створити 4 папки з розмірним файлом, наприклад

  1. res / values-hdpi / dimens.xml
  2. res / values-xhdpi / dimens.xml
  3. res / values-xxhdpi / dimens.xml
  4. res / values-xxxhdpi / dimens.xml

Тепер у файлі dimens.xml ви повинні розмістити розміри тексту. Я показую вам код для значень-hdpi , аналогічно вам потрібно розмістити код для інших значень роздільної здатності / dimens.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 пікселів

Це просте рішення для реалізації необхідного розміру тексту для всіх роздільних можливостей. Я тут не розглядаю пристрої з роздільною здатністю значень-MPD . Якщо хтось хоче включити розмір тексту для цієї роздільної здатності, тоді його співвідношення становить 3: 4: 6: 8: 12 . Будь-який запит, будь ласка, дайте мені знати. Сподіваємось, це допоможе вам вийти з людей.


4
Чи не погана практика використовувати px замість sp у розмірі тексту? Чи є спосіб досягти наступного співвідношення, використовуючи sp замість px?
Червоний М

Я перевірив, що це працює нормально, але я все одно збентежений, чи є хорошою практикою використовувати значення в px замість dp / sp? Я ніколи не бачив десь з офіційної документації використовувати значення в px.
shaby

1
використовувати sp для розміру шрифту, це закон. Підхід, який показав Рахул, є правильним, просто використовуйте sp замість px.
Міхір Патель

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замість цього.
Yousha Aleayoub

будь ласка, використовуйте sp для розміру тексту
Thinsky

Ви можете використовувати dp в конкретних ситуаціях, коли ви не хочете, щоб він міняв розмір на основі переваг користувача.

7

Кожен може скористатися наведеною нижче бібліотекою Android, що є найпростішим способом зробити розмір тексту сумісним практично з усіма екранами пристроїв. Він фактично розроблений на основі нових кваліфікаторів для конфігурації Android для розміру екрана (представленого в Android 3.2) SmallestWidth swdp.

https://github.com/intuit/sdp


2
sdp - для розміру екрана; використовувати ssp для розміру тексту
ecle

Це працює для мене, але я підозрюю, що є занадто багато файлів, щоб додати, це збільшить розмір програми, @Muhammad ви можете змінити розмір і додати лише класи будь-яких потреб
Kirtikumar A.

1

Якщо у вас є API 26, ви можете скористатися функцією autoSizeTextType :

<Button
  app:autoSizeTextType="uniform" />

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

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


Проблема в цьому полягає в тому, що він не змінює рівномірно розмір тексту для декількох переглядів тексту за допомогою рядків різної довжини
Sourabh S Nath

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


2
Використовуйте значення res / value-small може бути краще.
einverne

1
одна з гірших реалізацій. нам потрібно підтримувати 5 макетів просто для підтримки різних розмірів?
SolidSnake

Створення різних макетів для зменшення розміру тексту на варіантах екранів - це дуже погана ідея. Не рекомендую цього
Саман Салехі

0

Щоб уніфікувати всі екрани, щоб відобразити однакові розміри елементів, включаючи розмір шрифту: - Розробіть інтерфейс користувача на одному розмірі екрана з будь-якими розмірами, які ви вважаєте підходящими під час проектування, тобто розмір шрифту TextView становить 14dp за розміром екрана за замовчуванням із 4'6 дюймами.

  • Програмно розрахувати фізичний розмір екрану інших телефонів, тобто 5'2 дюймів інших телефонів / екранів.

  • Використовуйте формулу для обчислення відсоткової різниці між двома екранами. тобто відсоткова різниця між 4'6 і 5'2.

  • Обчисліть різницю пікселів між 2 TextView, виходячи з вищевказаної формули.

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

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

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


0

Ви також можете використовувати weightSumіlayout_weight властивість, щоб налаштувати ваш інший екран.

Для цього вам потрібно зробити android:layout_width= 0dp і android:layout_width= (що завгодно);



-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як посилання, до якого можна додати постійний чи сприйманий розмір (шляхом обчислення).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.