Как профессионально организовать стилизацию кнопок? (SDK 26+, мин SDK 21)
Как лучше организовать стилирование кнопок профессионального приложения для Android? Предположим большее современное приложение (SDK 26+, мин SDK 21).
Этот вопрос является ответственным, так как оба источника Material Design
и настройка Android Studio
дать достаточно подсказок и примеров моделей предполагаемого профессионального использования. Конечно, пользователь не ограничивается этими шаблонами, но следуя им, приложение хорошо взаимодействует с источниками Material Design
и обеспечивает лучшую ремонтопригодность.
Я нахожу несколько ингредиентов, связанных со стилем кнопок.
@style/Widget.AppCompat.Button
@style/Widget.AppCompat.Button.Colored
@style/TextAppearance.AppCompat.Button
@style/TextAppearance.AppCompat.Widget.Button
@color/foreground_material_dark
?colorAccent
?textColorPrimary
?android:colorForeground
?textAppearanceButton
Там может быть больше.
- Как связаны все ингредиенты?
- Как они предназначены для совместного использования в профессиональной тематике?
Вы можете посмотреть источники. Однако даже знание всех деталей не дает полной картины предполагаемого использования. Этот вопрос просит нарисовать картинку.
2 ответа
(Мин. SDK 21)
Общий подход
Зернистость
Я думаю, что это достаточно детальный подход, чтобы отделить внешний вид текста от фона. Это дает возможность комбинировать разные фоны с разным текстом. Он также соответствует двум настройкам стиля, предоставленным Button
и организация Материального Дизайна. Следовательно, он решает вопрос, как он предназначен для использования.
Цена в том, что каждый Button
нужны обе настройки:
- Текст кнопки:
android:textAppearance
- Фон кнопки:
style
Чтобы даже снизить эту цену styles_material.xml
на самом деле занимает передовой подход. Каждая кнопка style
уже включает внешний вид текста по умолчанию. Так что в обычном случае мне нужно только нажать кнопку style
,
<Button
style="?defaultButtonStyle"
Я придерживаюсь этого шаблона для моего собственного стиля кнопок, так как вопрос для предполагаемого использования. Если я хочу изменить значение по умолчанию, я добавляю альтернативный вид текста, устанавливая его в android:textAppearance
,
<Button
style="?defaultButtonStyle"
android:textAppearance="?smallButtonTextAppearance"
Для очень специальных кнопок я все еще могу настроить стиль на уровне файла макета. Это самый низкий уровень детализации.
Подсказка: знайте, что
android:textAppearance
имеет очень низкий приоритет. Если вы установите текстовый атрибут где-то в теме (или стиле), вы будете перезаписывать один и тот же атрибут во всехandroid:textAppearance
, Он работает с такой же силой, как аннотация "! Важно" в CSS, что может быть довольно ловушкой.
Гибкая тематика
Без
Если я не планирую использовать разные темы, я могу установить стили непосредственно в макетах.
<Button
style="@style/My.DefaultButtonStyle"
android:textAppearance="@style/My.SmallButtonTextAppearance"
...
С
Если вы хотите обмениваться темами, я сначала сопоставляю все типы стилей с атрибутами. Затем я устанавливаю стили косвенно, используя атрибуты. Это дает мне возможность подключать другие стили для других тем без необходимости дублировать макеты.
<Button
style="?defaultButtonStyle"
android:textAppearance="?smallButtonTextAppearance"
...
Лично я предпочитаю не использовать или смешивать данные атрибуты, но полностью определить свой собственный набор атрибутов, касающихся моего дизайна. Таким образом, уровни лука остаются чисто разделенными.
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<!-- button text appearance -->
<attr name="defaultButtonTextAppearance" format="reference" />
<attr name="smallButtonTextAppearance" format="reference" />
<!-- button backgrounds -->
<attr name="defaultButtonStyle" format="reference" />
<attr name="alarmButtonStyle" format="reference" />
В темах атрибуты сопоставляются с конкретными стилями темы.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="OtherTheme" parent="Theme.AppCompat">
<!-- button text appearance -->
<item name="defaultButtonTextAppearance">@style/OtherTheme.DefaultButtonTextAppearance</item>
...
<!-- button backgrounds -->
<item name="defaultButtonStyle">@style/OtherTheme.DefaultButtonStyle</item>
...
Текст кнопки
Если я отслеживаю стили до источников, я прихожу к файлу data/res/values/styles_material.xml
, который определяет корень всех появлений текста кнопки. TextAppearance.Material.Button
наследуется от TextAppearance.Material
, но четыре соответствующих атрибута для кнопок перезаписываются.
<style name="TextAppearance.Material">
<item name="textColor">?attr/textColorPrimary</item>
<item name="textColorHint">?attr/textColorHint</item>
<item name="textColorHighlight">?attr/textColorHighlight</item>
<item name="textColorLink">?attr/textColorLink</item>
<item name="textSize">@dimen/text_size_body_1_material</item>
<item name="fontFamily">@string/font_family_body_1_material</item>
<item name="lineSpacingMultiplier">@dimen/text_line_spacing_multiplier_material</item>
</style>
<style name="TextAppearance.Material.Button">
<item name="textSize">@dimen/text_size_button_material</item>
<item name="fontFamily">@string/font_family_button_material</item>
<item name="textAllCaps">true</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
Это может быть переписано моими собственными унаследованными стилями. Это также показывает, что было бы легко написать собственный стиль отображения текста без использования наследования вообще.
цвет
Понимание системы управления цветом текста в Android - их самая запутанная часть, потому что система довольно мощная. Здесь приходит некоторое просветление.
В выше TextAppearance.Material.Button
Я считаю, что цвет текста указан атрибутом ?textColorPrimary
, Этот атрибут снова основан на атрибуте ?android:colorForeground
,
Атрибут ?android:colorForeground
является центральным переключателем для установки цветов текста. По умолчанию все цвета текста рассчитываются на основе этого параметра, а также цвета кнопок. Например, для неактивных кнопок, для основного текста и т. Д. Рассчитываются различные оценки серых или непрозрачных вариантов.
Вместо того, чтобы касаться десятков разных мест, лучше установить здесь общий цвет текста по умолчанию и полагаться на систему вычисления цвета Android по умолчанию. Настроить это в деталях.
<item name="android:colorForeground">@color/orange_700</item>
Этот параметр по умолчанию @color/foreground_material_dark
,
Совет 1: если вы редактируете настройку с помощью
Android Studio Theme Editor
, это, возможно, изменит значение@color/foreground_material_dark
, Для меня не очень хорошая идея изменить значение материальной темноты, потому что это не моя сфера. Лучше использовать ссылку, как показано выше.Подсказка 2:
Theme Editor
является подходящим инструментом для выявления отношений системы атрибутов цвета. Эти отношения раскрываются, когда вы экспериментально пытаетесь редактировать различные атрибуты с помощью редактора.
Если я хочу, чтобы цвет текста кнопки отличался от общего цвета текста, я устанавливаю его на уровне стиля оформления текста.
Подсказка 3: Использование
?android:colorForeground
не работает из
поле ниже API 26. Обходной путь см. здесь.
Размер текста
Размер текста - это фактор внешнего вида текста, который я обычно хочу адаптировать к своему собственному дизайну в рамках моих собственных стилей отображения текста.
<style name="My.SmallButtonTextAppearance" parent="My.DefaultButtonTextAppearance">
<item name="android:textSize">16sp</item>
</style>
TextAppearance.Material.Button
принимает размер текста по умолчанию из ресурса @dimen/text_size_button_material
, Не существует системы с центральной настройкой размера текста, сравнимой с системой настройки цвета текста.
Все шапки
Корневой стиль TextAppearance.Material.Button
установить все заглавные буквы true
, Нет даже ресурса, значение взято из. Это просто жестко закодировано.
<item name="textAllCaps">true</item>
Есть большая вероятность, я хочу установить его false
в моих индивидуальных стилях кнопок.
<item name="android:textAllCaps">false</item>
Семейство шрифтов
Как и в случае с цветами текста, семейство шрифтов обычно представляет собой систему с общей центральной природой. Как это управляется для кнопок? Корневой стиль TextAppearance.Material.Button
делает использование строкового ресурса @string/font_family_button_material
,
<item name="fontFamily">@string/font_family_button_material</item>
В файле data/res/values/donttranslate_material.xml
это установлено на sans-serif-medium
в то время как в файле data/res/values-watch/donttranslate_material.xml
это установлено на sans-serif-condensed
,
<string name="font_family_button_material">sans-serif-medium</string>
<string name="font_family_button_material">sans-serif-condensed</string>
это sans-serif
Настройки отображаются в выбранном семействе шрифтов в настройках шрифтов. типично sans-serif
хорошо для текста кнопки. Для дальнейшей настройки шрифтов я укажу на этот вопрос.
Стиль кнопки
Помимо использования цвета для фона, можно применить файл ресурсов xml, чтобы указать фон с причудливыми углами, цветовыми градиентами или другими графическими эффектами, также поддерживая разные фоны для разных состояний кнопки.
На эту часть сильно повлиял мой дизайн. Я обычно буду использовать свой собственный фон.
С другой стороны, существует богатая система предопределенных файлов ресурсов фонов кнопок в дизайне материала. Я хотел бы дать краткий обзор здесь, но это выходит за рамки моих навыков и кажется настолько большим, что стоит отдельной темы.
style
для фона не должно содержать настроек для width
, height
или же margins
, так как это относится к окружающей обстановке. С другой стороны padding
принадлежит на задний план style
,
Стили кнопок дизайна материалов
В файле data/res/values/styles_material.xml
Я нахожу девять стилей кнопок, от которых я могу наследовать. Если я пишу свой собственный, не следует забывать устанавливать внешний вид текста по умолчанию.
Корневой элемент Widget.Material.Button
, По умолчанию текстовое оформление установлено на ?textAppearanceButton
, Следовательно, установка этого атрибута позволяет напрямую использовать стили кнопок дизайна материала без наследования, но при этом иметь настроенный вид текста по умолчанию.
<!-- Bordered ink button -->
<style name="Widget.Material.Button">
<item name="background">@drawable/btn_default_material</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">88dip</item>
<item name="stateListAnimator">@anim/button_state_list_anim_material</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
Атрибут ?colorAccent
используется, чтобы установить цвет Widget.AppCompat.Button.Colored
, Увидеть Android Studio Theme Editor
, Увидеть @drawable/btn_colored_material
,
Обратите внимание, что по умолчанию внешний вид текста Widget.AppCompat.Button.Colored
варьируется и не устанавливается настраиваемым атрибутом.
<!-- Colored bordered ink button -->
<style name="Widget.Material.Button.Colored">
<item name="background">@drawable/btn_colored_material</item>
<item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Colored</item>
</style>
<!-- Small bordered ink button -->
<style name="Widget.Material.Button.Small">
<item name="minHeight">48dip</item>
<item name="minWidth">48dip</item>
</style>
<!-- Borderless ink button -->
<style name="Widget.Material.Button.Borderless">
<item name="background">@drawable/btn_borderless_material</item>
<item name="stateListAnimator">@null</item>
</style>
Обратите внимание, что по умолчанию внешний вид текста Widget.Material.Button.Borderless.Colored
варьируется и не устанавливается настраиваемым атрибутом.
<!-- Colored borderless ink button -->
<style name="Widget.Material.Button.Borderless.Colored">
<item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Borderless.Colored</item>
</style>
Обратите внимание, что Widget.Material.Button.ButtonBar.AlertDialog
наследуется от Widget.Material.Button.Borderless.Colored
, Применяются те же ограничения внешнего вида текста по умолчанию.
<!-- Alert dialog button bar button -->
<style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
<item name="minWidth">64dp</item>
<item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
</style>
<!-- Small borderless ink button -->
<style name="Widget.Material.Button.Borderless.Small">
<item name="minHeight">48dip</item>
<item name="minWidth">48dip</item>
</style>
<style name="Widget.Material.Button.Inset">
<item name="background">@drawable/button_inset</item>
</style>
<style name="Widget.Material.Button.Toggle">
<item name="background">@drawable/btn_toggle_material</item>
<item name="textOn">@string/capital_on</item>
<item name="textOff">@string/capital_off</item>
</style>
Лично я бы либо использовал один из этих предопределенных стилей кнопок, либо унаследовал свой собственный от Widget.Material.Button
, Это позволяет сохранить низкую иерархию наследования и легко читаемый код. Это спасает меня не более трех строк кода, если я наследую от другого стиля, в то время как код становится менее поддерживаемым.
Из этого правила есть исключения. Например @drawable/btn_borderless_material
это личное. Так что я либо должен унаследовать от Widget.Material.Button.Colored
или создайте копию файла.
аппендикс
Смежные вопросы
Атрибуты
- Определение пользовательских атрибутов
- Android Используйте пользовательские темы для изменения атрибутов стиля
- Android "? ColorPrimary" против "attr / colorPrimary"?
- Проблема наследования при использовании свойства androidTextapperance или стиля свойства
Цвета
- Установка цвета на основе темы
- Атрибут android:colorForeground не работает в темах API 23 android - определение цветов в пользовательских темах
шрифты
Это зависит от вас и зависит от вашего приложения.. также вы можете установить фон, используя XML-файл, например:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#8c0000" />
</shape>
</item>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#c62f2c" />
</shape>
</item>
</selector>