Глобальный стиль для нового com.google.android.material.textfield.TextInputEditText

Можно ли стилизовать новый компонент com.google.android.material.textfield.TextInputEditText, не устанавливая его для каждого дополнительного компонента?

Например:

Для нового TextInputLayout я могу установить стиль глобально следующим образом:

<style name="Theme.MyTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
                                .
                                .
                                .
    <item name="textInputStyle">@style/MyTextInputLayoutStyle</item>
</style>

Я ожидаю, что для TextInputEditText аналогичным образом, например:

<item name="editTextStyle">@style/MyTextInputEditTextStyle</item>

но это не работает

Вот аналогичный пост, но только для старых компонентов поддержки дизайна.

1 ответ

Решение

Согласно этому комментарию editTextStyle является правильным атрибутом для установки. https://github.com/material-components/material-components-android/blob/6c70169e8d4ae77429a9c57785e443b2a18b4aa3/lib/java/com/google/android/material/theme/res/values/attrs.xml#L85

Смотрите пример использования в следующих стилях: https://github.com/material-components/material-components-android/blob/6c70169e8d4ae77429a9c57785e443b2a18b4aa3/lib/java/com/google/android/material/textfield/res/values/styles.xml#L141

Обновлено: пожалуйста, установите @style/ThemeOverlay.MaterialComponents.TextInputEditText внутри вашего пользовательского TextInputLayoutStyle.

В TextInputLayout отменяет editTextStyle атрибут с помощью materialThemeOverlay атрибут.

Например, Widget.MaterialComponents.TextInputLayout.FilledBox имеет этот стиль по умолчанию:

<style name="Widget.MaterialComponents.TextInputLayout.FilledBox" parent="Base.Widget.MaterialComponents.TextInputLayout">
    <item name="materialThemeOverlay">
       @style/ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox
    </item>
    ....
</style>
<style name="ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
    <item name="editTextStyle">@style/Widget.MaterialComponents.TextInputEditText.FilledBox</item>
</style>

Чтобы определить глобально, вы должны определить стиль для TextInputLayoutрасширение одной из материальных тем.
Тогда вам нужно использовать новыйmaterialThemeOverlay атрибут. Это позволяет вам переопределить атрибуты темы приложения, и вы можете изменитьeditTextStyle атрибут.

Что-то типа:

  <style name="MyCustomOutlined" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
    <item name="materialThemeOverlay">@style/MyThemeOverlayOutlined</item>    
  </style>

Таким образом вы можете изменить editTextStyle (атрибут темы приложения) только для этого стиля компонента.

  <style name="MyThemeOverlayOutlined">
    <item name="editTextStyle">@style/MyTextInputEditText_outlinedBox</item>
  </style>

  <style name="MyTextInputEditText_outlinedBox" parent="@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox">
    <item name="android:paddingTop">8dp</item>
    <item name="android:paddingBottom">8dp</item>
    ....
  </style>

Наконец, вы можете назначить MyCustomOutlinedв конкретных TextInputLayout в макете:

    <com.google.android.material.textfield.TextInputLayout
        style="@style/MyCustomOutlined"
        .../>

или назначьте глобально в своей теме приложения, используя:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
   ....
   <item name="textInputStyle">@style/MyCustomOutlined</item>
</style>