覆盖 editTextStyle 不适用于最新的 Material 组件基本样式
Overriding editTextStyle doesn't work with latest Material Components base style
在我的一个应用程序中,我使用 Theme.MaterialComponents.Light.NoActionBar
作为基本样式。在这种我称之为 AppTheme
的样式中,我试图覆盖 editTextStyle
以为 com.google.android.material.textfield.TextInputEditText
提供自定义样式(根据源代码,它使用 R.attr.editTextStyle
作为默认样式)。
这是我当前的主题,与 TIEditText 和 TILayout 相关:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
[ primary and secondary colors, OnColors, etc.]
<item name="editTextStyle">@style/AppTheme.TextInputEditText</item>
<item name="textInputStyle">@style/AppTheme.TextInputLayout</item>
[ Custom attribute for testing, defined in attrs.xml ]
<item name="textInputEditTextStyle">@style/AppTheme.TextInputEditText</item>
</style>
出于某种原因,即使我设置了 editTextStyle
,如果我在代码中使用它,它也不会被应用:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilFirstName"
style="?attr/textInputStyle"
android:hint="@string/label_firstname"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/firstName"
style="?attr/editTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="@={viewModel.firstName}" />
</com.google.android.material.textfield.TextInputLayout>
但是,如果我将 firstName
的样式替换为 ?attr/textInputEditTextStyle
,它就可以工作了。
为什么我不能覆盖默认主题中的 editTextStyle
?这到底是怎么回事?
目标SDK为28,minSDK为21,Material库版本为1.1.0-alpha06
For some reason, even though I set editTextStyle, if I use it in code, it does not get applied
这是因为 TextInputLayout
的默认样式使用 materialThemeOverlay
属性覆盖了 editTextStyle
。
例如 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>
让我们跳过我们都认识到 Android 主题和风格是人类有史以来最荒谬的骇客和猜测荒地的部分。
这是对之前答案的扩展。同样傻'hack'。我可以通过设置 editTextStyle
来设置 TextInputEditText
的样式,但不是在它直观所属的位置,而是在嵌套在为 textInputStyle
定义的样式中的自定义 materialThemeOverlay
中。见证人:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- works fine -->
<item name="textInputStyle">@style/AppTheme.TextInputLayoutStyle</item>
<!-- should work fine, doesn't work, happily ignored -->
<!-- <item name="editTextStyle">@style/AppTheme.TextInputEditTextStyle</item> -->
</style>
<style name="AppTheme.TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<!-- other props (boxBackgroundMode, boxBackgroundColor, boxStrokeColor, etc) -->
<!-- can we set editTextStyle from here? Of course not! We should magically know we need a material theme overlay-->
<item name="materialThemeOverlay">@style/AppTheme.MaterialThemeOverlay</item>
</style>
<!-- style inception! a style, child of another style, whose only purpose is to refer to yet another style -->
<style name="AppTheme.MaterialThemeOverlay">
<item name="editTextStyle">@style/AppTheme.TextInputEditTextStyle</item>
</style>
<!-- finally, the style we SHOULD have been able to set from the theme -->
<style name="AppTheme.TextInputEditTextStyle" parent="@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox">
<item name="android:textColor">@color/white</item>
</style>
以上所有的荒谬和我生命中的另一天被扔进了垃圾桶,只是为了改变文本的颜色。 Thaaaaanks Aaaaaandroid.
在我的一个应用程序中,我使用 Theme.MaterialComponents.Light.NoActionBar
作为基本样式。在这种我称之为 AppTheme
的样式中,我试图覆盖 editTextStyle
以为 com.google.android.material.textfield.TextInputEditText
提供自定义样式(根据源代码,它使用 R.attr.editTextStyle
作为默认样式)。
这是我当前的主题,与 TIEditText 和 TILayout 相关:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
[ primary and secondary colors, OnColors, etc.]
<item name="editTextStyle">@style/AppTheme.TextInputEditText</item>
<item name="textInputStyle">@style/AppTheme.TextInputLayout</item>
[ Custom attribute for testing, defined in attrs.xml ]
<item name="textInputEditTextStyle">@style/AppTheme.TextInputEditText</item>
</style>
出于某种原因,即使我设置了 editTextStyle
,如果我在代码中使用它,它也不会被应用:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilFirstName"
style="?attr/textInputStyle"
android:hint="@string/label_firstname"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/firstName"
style="?attr/editTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="@={viewModel.firstName}" />
</com.google.android.material.textfield.TextInputLayout>
但是,如果我将 firstName
的样式替换为 ?attr/textInputEditTextStyle
,它就可以工作了。
为什么我不能覆盖默认主题中的 editTextStyle
?这到底是怎么回事?
目标SDK为28,minSDK为21,Material库版本为1.1.0-alpha06
For some reason, even though I set editTextStyle, if I use it in code, it does not get applied
这是因为 TextInputLayout
的默认样式使用 materialThemeOverlay
属性覆盖了 editTextStyle
。
例如 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>
让我们跳过我们都认识到 Android 主题和风格是人类有史以来最荒谬的骇客和猜测荒地的部分。
这是对之前答案的扩展。同样傻'hack'。我可以通过设置 editTextStyle
来设置 TextInputEditText
的样式,但不是在它直观所属的位置,而是在嵌套在为 textInputStyle
定义的样式中的自定义 materialThemeOverlay
中。见证人:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- works fine -->
<item name="textInputStyle">@style/AppTheme.TextInputLayoutStyle</item>
<!-- should work fine, doesn't work, happily ignored -->
<!-- <item name="editTextStyle">@style/AppTheme.TextInputEditTextStyle</item> -->
</style>
<style name="AppTheme.TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<!-- other props (boxBackgroundMode, boxBackgroundColor, boxStrokeColor, etc) -->
<!-- can we set editTextStyle from here? Of course not! We should magically know we need a material theme overlay-->
<item name="materialThemeOverlay">@style/AppTheme.MaterialThemeOverlay</item>
</style>
<!-- style inception! a style, child of another style, whose only purpose is to refer to yet another style -->
<style name="AppTheme.MaterialThemeOverlay">
<item name="editTextStyle">@style/AppTheme.TextInputEditTextStyle</item>
</style>
<!-- finally, the style we SHOULD have been able to set from the theme -->
<style name="AppTheme.TextInputEditTextStyle" parent="@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox">
<item name="android:textColor">@color/white</item>
</style>
以上所有的荒谬和我生命中的另一天被扔进了垃圾桶,只是为了改变文本的颜色。 Thaaaaanks Aaaaaandroid.