TextInputLayout выбрасывает Стиль этого компонента требует, чтобы тема вашего приложения была Theme.AppCompat (или ее потомком).

Я использую TextInputLayout, обернутый вокруг EditText для элемента RecyclerView. Я использую стиль «Theme.AppCompat.Light.NoActionBar». Но все же я получаю сообщение об ошибке «Причина: java.lang.IllegalArgumentException: стиль этого компонента требует, чтобы ваша тема приложения была Theme.AppCompat (или потомком)». Однако когда я удаляю TextInputLayout из xml приложение работает нормально.

Вот мой элемент 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>

AndroidManifest:

<?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

RecyclerAdapter:

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());
                    }
                }
            });
        }
    }
}

Есть предположения? Спасибо.


comment
Вы передаете Context своему RecyclerView.Adapter за LayoutInflater? Если да, то какой именно Context?   -  person Mike M.    schedule 19.09.2019
comment
См. Примечание из моего ответа здесь: stackoverflow.com/a/52401497/10271334   -  person Jeel Vankhede    schedule 19.09.2019
comment
Хорошо, каков первый аргумент в вашем new SettingsAdapter(???, ...) вызове?   -  person Mike M.    schedule 19.09.2019
comment
использовать материал для материала textinputLayout вместо обычной темы   -  person BlackBlind    schedule 19.09.2019
comment
@MikeM., Я передаю MainApplication.getInstance () в качестве контекста. частный статический MainApplication sInstance; общедоступный статический MainApplication getInstance () {return sInstance; }   -  person itabdullah    schedule 19.09.2019
comment
Вам нужно передать Activity, а не приложение Context. На нем не будет темы.   -  person Mike M.    schedule 19.09.2019
comment
@MikeM., Да. ты прав. Я прошел getActivity, и теперь он работает нормально. Как я могу принять ваш ответ? Большое спасибо.   -  person itabdullah    schedule 19.09.2019
comment
Без проблем. Похоже, вы, возможно, используете старую версию компонентов материала, потому что новые обеспечивают Theme.MaterialComponents - как Габриэле Мариотти ссылается ниже - а не Theme.AppCompat. Дайте ему минуту, и если он внесет поправки в свое сообщение, чтобы решить вашу конкретную текущую проблему, вы можете просто принять его ответ, поскольку в нем также есть важные советы для новых версий. В любом случае, спасибо. Я ценю предложение. Рад, что у тебя все получилось. Ваше здоровье!   -  person Mike M.    schedule 19.09.2019
comment
@MikeM. Спасибо за упоминание. Настоящая проблема - это контекст, который вы описали в своем комментарии. В любом случае с последней версией Material Components у него возникнет проблема другого рода.   -  person Gabriele Mariotti    schedule 20.09.2019


Ответы (3)


Как @MikeM. прокомментировал вопрос, есть проблема с контекстом, используемым для создания экземпляра Adapter. Вам необходимо передать Activity, а не Application Context.
В ApplicationContext отсутствует тема вашего приложения.

Но обратите внимание, поскольку вы используете com.google.android.material.textfield.TextInputLayout, отметьте документ библиотеки компонентов материала.
Тема вашего приложения должна быть унаследована от < a href = "https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md#material-components-themes" rel = "noreferrer"> Материал Тема компонентов.

Если вы не можете изменить свою тему, вы можете сделать одно из следующих действий:

person Gabriele Mariotti    schedule 19.09.2019
comment
Габриэле, спасибо. Теперь я использую ‹style name = AppTheme.Base parent = Theme.MaterialComponents.Light.NoActionBar›, и он работает нормально. Настоящая проблема - это контекст, упомянутый @MikeM. - person itabdullah; 21.09.2019

Если в действии есть компоненты, использующие этот контекст, другим решением будет получение объекта Context и установка его темы на AppCompat. Вот пример кода Kotlin:

 val context: Context = getApplicationContext()
 context.setTheme(R.style.your_theme_extending_AppCompatTheme)
 // Use this context throughout the class.
person sorry_I_wont    schedule 16.12.2020

Добавить атрибут tools для корневого тега

tools:context=".view.activities.Activity_where_should_be_displayed"
person Gagan Belgur    schedule 03.07.2020
comment
Это неправильно: атрибуты tools: не влияют на приложение во время выполнения. - person Ryan M; 04.07.2020