覆盖 editTextStyle 不适用于最新的 Material Components 基本样式

fon*_*232 11 android android-edittext android-textinputlayout material-components material-components-android

在我的一个应用程序中,我将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>
Run Code Online (Sandbox Code Playgroud)

出于某种原因,即使我设置了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>
Run Code Online (Sandbox Code Playgroud)

但是,如果我替换firstNamewith的样式?attr/textInputEditTextStyle,它会起作用。

为什么我不能覆盖editTextStyle默认主题?这到底是怎么回事?

目标 SDK 为 28,minSDK 为 21,材质库版本为 1.1.0-alpha06

rmi*_*lle 24

让我们跳过我们都认识到 Android 主题和风格是人类有史以来最荒谬的黑客和猜测荒地的部分。

这是对上一个答案的扩展。同样愚蠢的“黑客”。我能够TextInputEditText通过设置设置样式editTextStyle,但不是它直观所属的位置,而是在materialThemeOverlaytextInputStyle. 证人:

<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>
Run Code Online (Sandbox Code Playgroud)

以上所有的荒谬和我生命中的另一天都被扔进了垃圾桶,只是为了改变文本的颜色。Thaaaaanks Aaaaaandroid。

  • 非常感谢您)在我使用您的解决方案之前,这太令人困惑了。这低于我对所有样式都只是样式的理解,而这个特别是 themeOverlayed 样式 (2认同)
  • 这太荒谬了,谷歌。他们确实需要重新改进整个主题系统。感谢您为我节省了无数时间来解决这个问题。 (2认同)
  • 目前我们正在对我们的应用程序进行品牌重塑,我非常同意第一句话。投我一票吧! (2认同)

Gab*_*tti 7

出于某种原因,即使我设置了 editTextStyle,如果我在代码中使用它,它也不会被应用

发生这种情况是因为默认样式TextInputLayout覆盖了editTextStyleusingmaterialThemeOverlay属性。

例如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>
Run Code Online (Sandbox Code Playgroud)