Search code examples
androidtextviewspinnerandroid-theme

Spinner item text isn't being styled correctly when using dark mode of the material component DayNight theme


In our app, we're using Theme.MaterialComponents.DayNight.NoActionBar as the parent of our app's theme to implement a switchable day-night theme. It seems to be working everywhere in our app, except specifically the spinner item. The text of the spinner item is black when in dark theme. It's especially weird because the spinner dropdown items are coloured correctly.

Spinner Item

Spinner Dropdown Items

I've tried creating a custom layout for the spinner item:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:id="@+id/spinner_item_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"/>

But any attempts to apply styling to it using attributes from the theme causes the app to crash (e.g. adding android:textColor="?attr/colorOnPrimary" causes the app to crash when trying to inflate the spinner).

What I want is for the spinner item's TextView to be correctly coloured based on whichever theme is chosen with setDefaultNightMode(), just like every other TextView. If I'm missing anything important that I need to include, let me know.


Solution

  • Figured out what was wrong. The app was crashing because the spinner's TextView didn't have the theme applied to it. To get the spinner to theme correctly, I added a style to my spinner item:

    <?xml version="1.0" encoding="utf-8"?>
    <TextView
        android:id="@+id/spinner_item_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Objective.SpinnerItemTextView"
        xmlns:android="http://schemas.android.com/apk/res/android"/>
    

    The style looks like this:

    <style name="Objective.SpinnerItemTextView" parent="@android:style/Widget.TextView">
        <item name="android:theme">@style/Theme.Objective</item>
        <item name="android:textColor">?attr/colorOnBackground</item>
    </style>
    

    After these changes, the text color was still not changing when the theme changed. The issue was with the context I passed into the ArrayAdapter. Originally, I was passing in the application context, but apparently inflating with the application context does not apply style/theme. Changing to using a base context fixed this issue.

    ArrayAdapter.createFromResource(
        requireActivity().baseContext,
        R.array.deadline_types_array,
        R.layout.spinner_item).also { adapter ->
            adapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item)
            deadlineTypeDropdown.adapter = adapter
        }
    

    After these changes, the spinner was themed correctly. I haven't tested it, but you probably don't have to create a custom spinner layout. Instead, you could probably modify the ?android:attr/spinnerItemStyle to use a custom style, though again, I haven't tried this.