Как стать автором
Обновить

Стилизация Android-приложений и дизайн-система: как это сделать и подружить одно с другим

Время на прочтение8 мин
Количество просмотров18K
Всего голосов 10: ↑10 и ↓0+10
Комментарии10

Комментарии 10

Не очень понял в чём преимущество создания своих кастомных компонент над уже стандартными. В этом примере вы меняется дефолтный стиль.
Но разве мы не можем в темах и сейчас поменять стиль стандартных компонент без необходимости наследоваться? Всякие buttonStyle, materialButtonStyle, toolbarStyle и прочие аттрибуты..

Доброе утро! Ответил вам в отдельном треде ниже((
Посыл дизайн системы в том, чтобы определить там самые базовые элементы и минимизировать количество кода по применению этих компонентов в своих экранах. Нет ничего предрасудительного в том чтобы изменить дефолтный стиль и не заставлять всех писать в .xml style=«somestyle». При этом в случаях расхождения с дизайн системой никто не запрещает переопределить в верстке свой стиль элементу. Преимущество наследования view проявляется когда есть необходимость определять свое поведение, отличное от базового (а в подавляющем большинстве элементов это требуется). Согласен с вами, что простые текстовые view (как в примере) остро не нуждаются в наследовании (можно подпихнуть style из темы и переключать), но как мне кажется удобно при чтении верстки сразу видеть что за компонент перед вами (H1/H2/H3 Component, ListItemComponent, ButtonComponent and etc.,) без чтения нюансов из style тэга. При создании экранов дизайнеры маркируют элементы (у нас в фигме) как компонент дизайн системы и при верстке можно сразу вставлять компонент дизайн системы и донастраивать его при необходимости.

А что входит в компонент по-умолчанию? Может привести несколько примеров реальных из проекта?
Например, ваш H1/H2/H3 Component. В нём определяются только размеры текста?
А например цвет куда? Или цвет это уже внешняя стилизация компонента?

По умолчанию в компоненте его базовый конструктор с отсылкой на стиль. Как пример текстовый компонент заголовков H1 (названия вдохновлены web-ом):
class H1Component @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = R.attr.cm_header1_style
) : AppCompatTextView(context, attrs, defStyleAttr)


А в стиле компонента («ThemeOverlay») определение его атрибутов:
<style name="Header1" parent="BaseTextWidget">
        <item name="android:textSize">28sp</item>
        <item name="lineHeight">34sp</item>
        <item name="fontFamily">@font/roboto_bold</item>
    </style>

    <style name="Header1.Light">
        <item name="android:textColor">@color/component_black</item>
    </style>

    <style name="Header1.Dark">
        <item name="android:textColor">@color/component_white_night</item>
    </style>


При такой реализации разработчикам не нужно думать о том какие стили прописать и какие шрифты, все за них уже определено.
Остается лишь добавить компонент в верстку и не прописывать ничего лишнего:
 <com.citymobil.designsystem.text.H1Component
         android:id="@+id/title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="I will be back"/>

Я не очень понял зачем упарываться рантайм перекраской. Да, «моргания» действительно нет, но смена темы это сравнительно редкое явление, которым можно пренебречь, а вот обмазывать каждую вью для перекраса рантаймом это очень дорого в разработке.
Согласен что упарываться не стоит, как раз таки далее я рассмотрел в статье иной подход который нам подходит больше (Ситимобилу).
Но на одном из проектов в читалке (LitRes) требовалось сделать смену темы без моргания и были строго определены 3 темы, потому был применен первый подход. Обмазать каждую view не было очень дорого поскольку был однотипный UI (можно было большую часть элементов красить однотипно, была написана схема перекраски: на входе бралась parent view экрана, на выходе был полностью перекрашенный экран).
if (view is TextView) {
    (view as TextView).setTextColor(
        if (darkMode) R.color.blue else R.color.black
    )
} else if (view is TabLayout) {
  (view as TabLayout).doAnything()
}

После is не нужен явный каст же
Зарегистрируйтесь на Хабре, чтобы оставить комментарий