使用TextInputLayout时出现InflateException异常

50

我正在尝试使用来自Material Design的TextInputEditText(https://github.com/material-components/material-components-android/blob/master/docs/components/TextInputLayout.md),但我遇到了运行时异常。

这是运行日志的一部分:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.grigori.materialtextedit, PID: 12036
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.grigori.materialtextedit/com.example.grigori.materialtextedit.MainActivity}: android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.google.android.material.textfield.TextInputLayout
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
                  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
                  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
                  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
                  at android.os.Handler.dispatchMessage(Handler.java:106)
                  at android.os.Looper.loop(Looper.java:193)
                  at android.app.ActivityThread.main(ActivityThread.java:6669)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
               Caused by: android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.google.android.material.textfield.TextInputLayout
               Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class com.google.android.material.textfield.TextInputLayout
               Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.material.textfield.TextInputLayout" on path: DexPathList

我使用包含许多apk文件路径的DexPathList来切分这个日志,例如:
zip file "/data/app/com.example.grigori.materialtextedit-jamgTcrgG9neBKIMcqDo7Q==/base.apk"

我的xml文件:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/hint_text"/>

</com.google.android.material.textfield.TextInputLayout>

我的build.gradle依赖:

    dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'}     

1
对我来说也是同样的问题,我已经在build.gradle中添加了实现。它可以在几乎所有设备上运行。但是在一些vivo设备上,每次都会崩溃。有什么想法为什么这个问题只出现在vivo设备上? - Midhun Murali
31个回答

49

在我的现有项目中实现 AndroidX 时遇到了这个问题。

implementation 'com.google.android.material:material:1.0.0-beta01'

布局 XML

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/userNameWrapper"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/TextLabel">

旧式风格

<style name="TextLabel" parent="TextAppearance.AppCompat">
        <item name="android:textColorHint">@color/hint_color</item>
        <item name="android:textSize">@dimen/text_20sp</item>
        <item name="colorControlNormal">@color/primaryGray</item>
        <item name="colorControlActivated">@color/colorPrimary</item>
    </style>

新风格

<style name="TextLabel" parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
        <item name="android:textColorHint">@color/hint_color</item>
        <item name="android:textSize">@dimen/text_20sp</item>
        <item name="colorControlNormal">@color/primaryGray</item>
        <item name="colorControlActivated">@color/colorPrimary</item>
    </style>

我认为如果用户使用androidx,则不需要添加implementation 'com.google.andr......'的实现。 - giveJob
分享提示颜色的样式。 - Atif AbbAsi

34

通过继承以下主题之一,在@style文件夹中更新您的主题:

Theme.MaterialComponents
Theme.MaterialComponents.NoActionBar
Theme.MaterialComponents.Light
Theme.MaterialComponents.Light.NoActionBar
Theme.MaterialComponents.Light.DarkActionBar

像这样:

    <style name="AppTheme.NoActionBar"    parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimaryCustom</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDarkCustom</item>
    <item name="colorAccent">@color/colorAccentCustom</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

我的问题是,我试图使用父级为“Theme.AppCompat.Light.NoActionBar”的样式,并且一些小部件是Material Design的。它们似乎不能很好地协同工作。(我正在学习Android,这是我修复崩溃应用程序的方法)。 - Ikon

25

可能只是一个主题问题。如果您的TextInputLayout的父级是MaterialComponents(如下所述)

<style name="TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
   ...
</style>

如果您的 Activity (或应用程序的)主题派生自 AppCompat,则您的应用程序将崩溃,因为 MaterialComponents 和 AppCompat 主题不兼容。例如,AppTheme(用于 Activity 或 App)不能如下所示:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

你还需要将你的AppTheme设置为MaterialComponents,如下所示:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
   <item name="colorPrimary">@color/colorPrimary</item>
   <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
   <item name="colorAccent">@color/colorAccent</item>
</style>
希望这可能起作用。

希望这可能起作用。


16

感谢您的回答。问题在于我使用了com.google.android.material.textfield.TextInputLayout。如果您使用此控件,则应在依赖项中添加:

implementation 'com.google.android.material:material:1.0.0-beta01'

在我的情况下,我将xml重写为android.support.design.widget.TextInputLayout

    <android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColorHint="@color/colorPrimary"
    app:errorEnabled="true">

    <android.support.design.widget.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorPrimary"
        android:textColorHint="@color/colorPrimary"
        android:hint="Username" />

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

另外,我在我的依赖中添加了:

implementation 'com.android.support:design:27.1.1'

这解决了我的问题。


14

我在使用AndroidX时也遇到了相同的错误。我有一个解决方案,对我很有效。

不要使用Theme.AppCompat,而是将Theme.MaterialComponents样式用作AppTheme或活动的样式。

style.xml

Translated text:

我在使用AndroidX时也遇到了相同的错误。我有一个解决方案,对我很有效。

不要使用Theme.AppCompat,而是将Theme.MaterialComponents样式用作AppTheme或活动的样式。

style.xml

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

使用Google Material Library。

implementation 'com.google.android.material:material:1.2.0'

为什么会出现这个问题?

我注意到你正在使用自定义样式的TextInputLayout:style="@style/TextInputLayout"

应该使用@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox或类似的样式。因此,需要在Activity的父主题中使用Theme.MaterialComponents


1
我能够避免这个问题,只需在样式中使用MaterialComponents而不是AppCompat,避免使用材料库的Alpha通道。 - Ariel

10

实际上,大多数人声称的 AppTheme 不正确!

如果你正在使用 androidx 并且不想要一个 MaterialComponents AppTheme

<!--style name="AppTheme" parent="Theme.MaterialComponents..."-->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

您可以始终执行以下操作,并仅将MaterialComponents主题添加到父容器:

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:theme="@style/Theme.MaterialComponents">

            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/performing_attr1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Label"
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="number"/>
            </com.google.android.material.textfield.TextInputLayout>

8

将应用程序主题更改为继承自Material Components主题

<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
   <!-- ... -->
</style>

5
这个致命错误的主要原因是,在为文本输入布局设置样式时,非常需要同时更改应用程序的主题或者针对特定屏幕创建另一个样式。 可以通过以下步骤完成:
进入values 然后打开styles.xml
通常您的应用程序主题会像这样。
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

这里需要改变的主要内容是:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">

将appcompat更改为Material组件

如果您不想更改应用程序主题

<style name="MaterialAppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">


我认为这会很好地起到作用,帮助你扩大输入框中的轮廓框或任何特定主题。

5
在应用程序的 Gradle 中添加此依赖项。
implementation 'com.google.android.material:material:1.1.0-alpha09'

在style.xml中为您的TextInputLayout添加此样式

<style name="TextLabel" parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
    <item name="android:textColorHint">@color/colorGray600</item>
    <item name="android:textSize">@dimen/text_20sp</item>
    <item name="colorControlNormal">@color/colorGray900</item>
    <item name="colorControlActivated">@color/colorPrimary</item>
</style>

在TextInputLayout中添加以下内容:

android:theme="@style/TextLabel"

确保您已经使用了适当的主题作为父主题,就像这样

Theme.MaterialComponents.Light

现在这将解决InflateException问题。 但是如果您有矢量图形,请按照以下步骤进行操作

1. 您需要在应用的build.gradle中选择AndroidX矢量支持:

android {
...
defaultConfig {
    ...
    vectorDrawables.useSupportLibrary = true
} }

2. 如果你想要以声明的方式(在你的布局中)设置可绘制对象,那么appcompat提供了许多*Compat属性,你应该使用这些属性代替标准平台属性:

ImageView, ImageButton:

不要使用:android:src 改用:app:srcCompat

CheckBox, RadioButton:

不要使用:android:button 应该使用:app:buttonCompat TextView(自版本 appcompat:1.1.0 起): 不要使用:android:drawableStart android:drawableTop 等属性。 应该使用:app:drawableStartCompat app:drawableTopCompat 等属性。

由于这些属性是 appcompat 库的一部分,请务必使用 app 命名空间。在内部,这些 AppCompat* 视图本身使用 AppCompatResources 来启用矢量图的加载。

3. 如果您想在代码中使用,则:

val drawable = AppCompatResources.getDrawable(context, R.drawable.my_vector)

**4.**如果您正在使用数据绑定,则可以使用自定义绑定适配器来完成此操作:

/* Copyright 2018 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
@BindingAdapter("indeterminateDrawableCompat")
fun bindIndeterminateProgress(progressBar: ProgressBar, @DrawableRes id: Int) {
  val drawable = AppCompatResources.getDrawable(progressBar.context, id)
  progressBar.indeterminateDrawable = drawable
}

希望这可以解决问题。

4
如果你在进行仪器测试时遇到了这个错误,那么可能需要通过以下方式定义你的样式。 val scenario = launchFragmentInContainer<LoginFragment>(themeResId = R.style.MyTheme)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接