android - TextInputLayout 抛出 "The style on this component requires your app theme to be Theme.AppCompat (or a descendant)."

标签 android android-layout android-theme android-textinputlayout material-components-android

我正在为 RecyclerView 项目使用围绕 EditText 的 TextInputLayout。我正在使用样式“Theme.AppCompat.Light.NoActionBar”。但我仍然收到错误 “Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).” 但是,当我从 xml 中删除 TextInputLayout 时,应用程序运行正常。

这是我的 RecyclerView 项目 (item_content_settings):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:weightSum="20">

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="18"
        android:padding="16dp">

        <EditText
            android:id="@+id/content_summary"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:hint="First Name"
            android:inputType="text"
            android:text="First Name And Last Name" />

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

    <ImageView
        android:id="@+id/pencil"
        android:layout_width="0dp"
        android:layout_height="16dp"
        android:layout_gravity="center"
        android:layout_margin="0dp"
        android:layout_weight="2"
        android:src="@drawable/pencil_edit" />
</LinearLayout>

我的风格:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="AppTheme.Base">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!--    <style name="AppTheme.NoActionBar">-->
    <!--        <item name="windowActionBar">false</item>-->
    <!--        <item name="windowNoTitle">true</item>-->
    <!--    </style>-->

    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background</item>
    </style>


    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>

安卓 list :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sed.RP">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".SplashActivity"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme"></activity>

        <activity android:name=".WelcomeActivity" />
        <activity android:name=".LoginActivity" />
        <activity android:name=".SignupActivity" />
        <activity android:name=".ForgotPasswordActivity" />
        <activity android:name=".VerifyEmailActivity" />

    </application>

</manifest>

错误:

2019-09-19 14:20:31.276 30912-30912/com.sed.RP E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.sed.RP, PID: 30912
    android.view.InflateException: Binary XML file line #8: Binary XML file line #8: Error inflating class <unknown>
    Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
        at android.view.LayoutInflater.createView(LayoutInflater.java:652)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:812)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:752)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:883)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:846)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:522)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:430)
        at com.sed.RP.SettingsAdapter.onCreateViewHolder(SettingsAdapter.java:46)
        at com.sed.RP.SettingsAdapter.onCreateViewHolder(SettingsAdapter.java:23)
        at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6794)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5975)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3641)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4194)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
        at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1730)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1496)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at com.google.android.material.appbar.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:142)
        at com.google.android.material.appbar.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:41)
        at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1556)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:888)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at androidx.drawerlayout.widget.DrawerLayout.onLayout(DrawerLayout.java:1231)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
2019-09-19 14:20:31.277 30912-30912/com.sed.RP E/AndroidRuntime:     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:730)
        at android.view.View.layout(View.java:17666)
        at android.view.ViewGroup.layout(ViewGroup.java:5577)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2394)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2116)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1302)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6441)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:876)
        at android.view.Choreographer.doCallbacks(Choreographer.java:688)
        at android.view.Choreographer.doFrame(Choreographer.java:623)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:862)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:163)
        at android.app.ActivityThread.main(ActivityThread.java:6238)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
     Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
        at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:221)
        at com.google.android.material.internal.ThemeEnforcement.checkAppCompatTheme(ThemeEnforcement.java:196)
        at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:131)
        at com.google.android.material.internal.ThemeEnforcement.obtainTintedStyledAttributes(ThemeEnforcement.java:110)
        at com.google.android.material.textfield.TextInputLayout.<init>(TextInputLayout.java:266)
        at com.google.android.material.textfield.TextInputLayout.<init>(TextInputLayout.java:247)
            ... 80 more

回收器适配器:

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import ca.barrenechea.widget.recyclerview.decoration.StickyHeaderAdapter;

public class SettingsAdapter extends RecyclerView.Adapter<SettingsAdapter.MyViewHolder>
        implements StickyHeaderAdapter<SettingsAdapter.HeaderHolder> {

    private LayoutInflater inflater;
    private ArrayList<SettingsItem> items;
    private ClickListener clickListener;
    private SharedPreferences preferences;
    int count;
    private int yearInfoPos;


    public SettingsAdapter(Context context, ArrayList<SettingsItem> items, int count, int yearInfoPos) {
        inflater = LayoutInflater.from(context);
        this.items = items;
        this.count = count;
        this.yearInfoPos = yearInfoPos;
        preferences = PreferenceManager.getDefaultSharedPreferences(context);
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = inflater.inflate(R.layout.item_content_settings, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {

//        switch (position) {
//            case 0:
//                holder.contentSummary.setHint("First Name");
//                break;
//            case 1:
//                holder.contentSummary.setHint("Last Name");
//                break;
//            case 2:
//                holder.contentSummary.setHint("Email Address");
//                break;
//            case 3:
//                holder.contentSummary.setHint("Password");
//                break;
//        }
        holder.contentSummary.setHint(items.get(position).title);
        holder.contentSummary.setText(items.get(position).contentSummary);
    }

    @Override
    public int getItemCount() {
        return count;
    }

    public void setClickListener(ClickListener clickListener) {
        this.clickListener = clickListener;
    }

    @Override
    public long getHeaderId(int position) {

        if (position < 0) {
            return 0;
        } else if (position < 4) {
            return 4;
        } else if (position < yearInfoPos) {
            return yearInfoPos;
        } else if (position < (yearInfoPos + 2)) {
            return yearInfoPos + 2;
        } else {
            return count - 1;
        }

    }

    @Override
    public HeaderHolder onCreateHeaderViewHolder(ViewGroup parent) {
        final View view = inflater.inflate(R.layout.item_header_settings, parent, false);
        return new HeaderHolder(view);
    }

    @Override
    public void onBindHeaderViewHolder(HeaderHolder headerHolder, int position) {
        if (position < 0) {
            headerHolder.headerText.setText(R.string.settings_title1);
        } else if (position < 4) {
            headerHolder.headerText.setText(R.string.settings_title2);
        } else if (position < yearInfoPos) {
            headerHolder.headerText.setText(R.string.settings_title3);
        } else if (position < (yearInfoPos + 2)) {
            headerHolder.headerText.setText(R.string.settings_title4);
        } else {
            headerHolder.headerText.setText(R.string.settings_title5);
        }

    }

    public interface ClickListener {
        void itemClicked(int position);
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.content_summary)
        EditText contentSummary;
        @BindView(R.id.pencil)
        ImageView pencilEdit;

        public MyViewHolder(View itemView) {
            super(itemView);
            //contentSummary = itemView.findViewById(R.id.content_summary);
            ButterKnife.bind(this, itemView);

            pencilEdit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (clickListener != null) {
                        clickListener.itemClicked(getLayoutPosition());
                    }
                }
            });
        }
    }

    static class HeaderHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.text_header)
        TextView headerText;
        @BindView(R.id.image_header)
        ImageView headerImage;

        public HeaderHolder(View itemView) {
            super(itemView);

            ButterKnife.bind(this, itemView);
//            headerText = itemView.findViewById(R.id.text_header);
//            headerImage = itemView.findViewById(R.id.image_header);
        }
    }

    class AddItemHolder extends RecyclerView.ViewHolder {

        TextView addItem;

        public AddItemHolder(View itemView) {
            super(itemView);
            addItem = itemView.findViewById(R.id.add_item);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (clickListener != null) {
                        clickListener.itemClicked(getLayoutPosition());
                    }
                }
            });
        }
    }
}

有什么想法吗? 谢谢。

最佳答案

作为@MikeM。评论了用于实例化 Adapter 的上下文存在问题的问题。 您需要传递 Activity,而不是 Application Context
ApplicationContext 没有您的应用主题。

但请注意,因为您使用的是 com.google.android.material.textfield.TextInputLayout,检查 the doc Material 组件库。
您的应用主题应继承自 Material Components theme .

如果您无法更改主题,您可以执行以下操作之一:

关于android - TextInputLayout 抛出 "The style on this component requires your app theme to be Theme.AppCompat (or a descendant).",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58007372/

相关文章:

java - 处理自定义 View 中的布局

android - 灰色状态栏

android - 不适合 TextView 大小的文本后的 3 个点

android - 如何应用 android 应用程序的所有 TextInputEditText 的样式

android - 如何更改 Android Material 主题提醒中的强调色?

android - 搜索栏,我可以用 2 个拇指更改最小最大值

java - 使用 getLaunchIntentForPackage 时出现 NullPointerException

Android studio 布局预览没有获取我当前的主题

android - RecyclerView 自动滚动到 WebView/Fresco SimpleDraweeView item

android - 在 Eclipse 中管理项目依赖关系