androidbottomnavigationviewmaterial-components-androidandroid-11

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


When using com.google.android.material.bottomnavigation.BottomNavigationView in my app layout, I get the following error:

Caused by: android.view.InflateException: Binary XML file line #25 in com.example:layout/activity_main: Error inflating class com.google.android.material.bottomnavigation.BottomNavigationView

Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).

Note that this ONLY happens on Android 11 devices running dark mode. When using light mode in Android 11, everything works fine.

This is the base app theme:

<style name="AppStyle" parent="Theme.Material3.DayNight.NoActionBar">
<style name="AppStyle.NavActive" parent="Widget.Material3.BottomNavigationView.ActiveIndicator">
    <item name="android:color">@color/surface</item>
</style>

And this is used in theme/night:

<style name="AppStyle" parent="Theme.Material3.DayNight.NoActionBar">

Even if I change it to Theme.AppCompat, Theme.MaterialComponents, etc. the app will still crash.

Why is it so? Although the light and dark themes would be identical, the app will still crash in dark mode. And this does not happen in the newer Android versions. So far only Android 11 in dark mode has these issues.

These are the gradle versions used:

implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.appcompat:appcompat:1.6.1'

The answers from here:
The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant)
did not work.


AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission
            android:name="android.permission.WRITE_EXTERNAL_STORAGE"
            android:maxSdkVersion="29" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.VIBRATE" />
    
        <application
            android:allowBackup="true"
            android:enableOnBackInvokedCallback="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:localeConfig="@xml/locales_config"
            android:supportsRtl="false"
            android:theme="@style/AppStyle"
            android:usesCleartextTraffic="true"
            tools:targetApi="33">
    
            <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
    
            <activity
                android:name=".activities.MainActivity"
                android:windowSoftInputMode="stateHidden"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>


Activity layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/navbar_background"
        app:itemActiveIndicatorStyle="@style/AppTheme.NavActive"
        app:itemIconTint="@color/bottomnav_color"
        app:itemTextColor="@color/bottomnav_color"
        app:itemPaddingBottom="25dp"
        app:itemPaddingTop="10dp"
        app:menu="@menu/bottom_nav"/>

</LinearLayout>

Activity OnCreate:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);

        // Restore the state of the currently opened fragment
        if (savedInstanceState != null) {
            currentFragment = getSupportFragmentManager().getFragment(savedInstanceState, "currentFragment");
        }


        // Navigation bar init
        NavigationBarView bottomNav = findViewById(R.id.bottom_nav_menu);
        // If the current fragment is null, set the default fragment to be loaded
        if (currentFragment == null) {
            switch (preferences.s_launchwindow) {
                case SETTINGS:
                    currentFragment = SettingsFragment.newInstance();
                    bottomNav.setSelectedItemId(R.id.nav_settings);
                    break;
                case FEED:
                    currentFragment = FeedFragment.newInstance();
                    bottomNav.setSelectedItemId(R.id.nav_feed);
                    break;
                case SOURCES:
                    currentFragment = SourceFragment.newInstance(preferences);
                    bottomNav.setSelectedItemId(R.id.nav_content);
                    break;
                case DISCOVER:
                    currentFragment = DiscoverFragment.newInstance(preferences);
                    bottomNav.setSelectedItemId(R.id.nav_discover);
                    break;
            }
            getSupportFragmentManager().beginTransaction()
                      .replace(R.id.frame_container, currentFragment)
                      .commit();
        }
        bottomNav.setOnItemSelectedListener(item -> {
            int itemId = item.getItemId();
            if (itemId == bottomNav.getSelectedItemId()) {
                // The selected item is already active, do nothing
                return true;
            }
            preferences = PreferencesManager.loadPreferences(MainActivity.this);
            if (itemId == R.id.nav_settings) {
                currentFragment = SettingsFragment.newInstance();
            } else if (itemId == R.id.nav_feed) {
                currentFragment = FeedFragment.newInstance();
            } else if (itemId == R.id.nav_content) {
                currentFragment = SourceFragment.newInstance(preferences);
            } else if (itemId == R.id.nav_discover) {
                currentFragment = DiscoverFragment.newInstance(preferences);
            }

            return loadFragment(currentFragment);
        });

        bottomNav.findViewById(R.id.nav_feed).setOnLongClickListener(v -> {
            if (currentFragment instanceof FeedFragment) {
                FeedFragment feedFragment = (FeedFragment) currentFragment;
                feedFragment.scrollToTop();
                return true; // Event has been consumed
            }
            return false; // Event has not been consumed
        });


Solution

  • Solution:

    Check that all the color values are set correctly in your theme. If some values, such as textPrimary or colorAccent are set to values that do not exist, the crash occurs.

    Also the crash message is very misleading, the issue had nothing to do with Theme.AppCompat