Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am using TextInputLayout wrapped around a EditText for a RecyclerView item. I am using style "Theme.AppCompat.Light.NoActionBar". But still I get the error "Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant)." However when I remove the TextInputLayout from the xml, the App runs fine.

Here is my RecyclerView item (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>

My Style:

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

error:

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

Any thoughts? Thanks.

like image 300
itabdullah Avatar asked Sep 19 '19 09:09

itabdullah


2 Answers

As @MikeM. commented on the question there is an issue with the context used to instantiate the Adapter. You need to pass the Activity, not an Application Context.
The ApplicationContext doesn't have your app theme.

But pay attention because you are using the com.google.android.material.textfield.TextInputLayout, check the doc of the Material Components library.
Your app theme should inherit from a Material Components theme.

If you can't change your theme, you can do one of the following:

  • Inherit from one of our Material Components Bridge themes.
  • Continue to inherit from an AppCompat theme and add some new theme attributes to your theme.
like image 56
Gabriele Mariotti Avatar answered Oct 18 '22 02:10

Gabriele Mariotti


If there are components in the activity that use that context, another solution would be to get the Context object, and set its theme to AppCompat. Here's the Kotlin code example:

 val context: Context = getApplicationContext()
 context.setTheme(R.style.your_theme_extending_AppCompatTheme)
 // Use this context throughout the class.
like image 6
sorry_I_wont Avatar answered Oct 18 '22 02:10

sorry_I_wont