Стиль пользовательского атрибута TextInputLayout из темы

В исходнике библиотеки дизайна мы можем найти эту строку:

<declare-styleable name="TextInputLayout">
    <attr format="reference" name="hintTextAppearance"/>
    <attr name="android:hint"/>
    <attr format="boolean" name="errorEnabled"/>
    <attr format="reference" name="errorTextAppearance"/>
    <attr format="boolean" name="counterEnabled"/>
    <attr format="integer" name="counterMaxLength"/>
    <attr format="reference" name="counterTextAppearance"/>
    <attr format="reference" name="counterOverflowTextAppearance"/>
    <attr name="android:textColorHint"/>
    <attr format="boolean" name="hintAnimationEnabled"/>
</declare-styleable>

Я хочу изменить цвет текста ошибки через атрибут errorTextAppearance

Я знаю, как настроить его через приложение: {имя-атрибута} в XML-декларации TextInputLayout, но как я могу настроить один из этих атрибутов из определения моей темы?




Ответы (2)


Чтобы упростить задачу, у вас есть настраиваемое представление, содержащее набор атрибутов. Для предоставления значений есть три разных способа снизу (представление) вверх (приложение).

  1. Предоставление значений представлениям из атрибутов или программно
  2. Создавайте разные стили и назначайте их этому представлению с помощью style="@style/MyStyle"
  3. Создайте атрибут и назначьте его параметру defStyleAttr конструктора вашего пользовательского представления. И назначьте стиль этому атрибуту в своей теме и вуаля!!

Для первых двух это прямолинейно. Сосредоточимся на последнем способе. Для этого есть четыре шага

Шаг 1

Создайте атрибут (обычно в файле res/values/attrs.xml

<resources>
    <attr name="myCustomViewAttr" format="reference" />

    <!-- Below are your set of attributes in declare styleable -->
    <declare-styleable name="TextInputLayout">
       <attr format="reference" name="hintTextAppearance"/>
       <attr name="android:hint"/>
       <attr format="boolean" name="errorEnabled"/>
       <attr format="reference" name="errorTextAppearance"/>
       <attr format="boolean" name="counterEnabled"/>
       <attr format="integer" name="counterMaxLength"/>
       <attr format="reference" name="counterTextAppearance"/>
       <attr format="reference" name="counterOverflowTextAppearance"/>
       <attr name="android:textColorHint"/>
       <attr format="boolean" name="hintAnimationEnabled"/>
    </declare-styleable>
</resources>

Шаг 2

Использование этого недавно созданного атрибута внутри вашего пользовательского представления.

Предполагая, что имя класса вашего пользовательского представления — MyCustomView. Конструктор вашего класса будет выглядеть примерно так

class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = R.attr.myCustomViewAttr
) : TextInputLayout(context, attrs, defStyleAttr)

Это заставит MyCustomView использовать атрибуты из myCustomViewAttr, если для атрибутов в макете ничего не указано.

Шаг 3

Создайте стиль, который является самым простым и используется большинством из них.

<style name="Widget.MyApp.MyCustomView" parent="">
   <!-- Assuming you have already defined TextAppearance.MyApp.ErrorText as you required -->
   <item name="errorTextAppearance">@style/TextAppearance.MyApp.ErrorText</item>
</style>

В случае, если вы хотите присвоить вашему errorTextAppearance какой-то другой атрибут, тогда

<style name="Widget.MyApp.MyCustomView" parent="">
   <!-- Assuming you have already defined TextAppearance.MyApp.ErrorText as you required -->
   <item name="errorTextAppearance">?attr/myAnotherDefinedAttribute</item>
</style>

Шаг 4

Последний и последний шаг, назначьте стиль атрибуту

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
   <item name="myCustomViewAttr">@style/Widget.MyApp.MyCustomView</style>
</style>

Если внешний вид вашего текста исходит из какого-то другого атрибута, вы можете напрямую назначить атрибут

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
   <item name="myCustomViewAttr">?attr/textAppearanceForError</style>
</style>
person Jimit Patel    schedule 11.12.2020

стили.xml:

<style name="TextInputLayout.Error" parent="@style/TextAppearance.Design.Error">
    <item name="android:textColor">@color/textinput_error_color</item>
</style>

<style name="Theme.AppName.TextInputLayout" parent="@style/Widget.Design.TextInputLayout">
    <item name="errorTextAppearance">@style/TextInputLayout.Error</item>
</style>

в вашем макете:

<android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/Theme.AppName.TextInputLayout">

                ...
            </android.support.design.widget.TextInputLayout>

Также вы можете добавить другие предметы из Widget.Design.TextInputLayout в Theme.AppName.TextInputLayout

person DeKaNszn    schedule 10.02.2016
comment
Спасибо, что нашли время ответить. :-) Когда я писал в рамках темы, мне было интересно, как применить этот стиль, используя атрибут обобщения темы. (Без применения стиля или атрибута непосредственно к TextInputLayout.) - person Pol; 10.02.2016