Как профессионально организовать стилизацию кнопок? (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 или создайте копию файла.

аппендикс

Смежные вопросы

Атрибуты

Цвета

шрифты

Это зависит от вас и зависит от вашего приложения.. также вы можете установить фон, используя 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>
Другие вопросы по тегам