Lahiru Chandima
Lahiru Chandima

Reputation: 24068

Customize theme of a single View

I need to set Spinner selected item color to white in a Spinner, which is on a Toolbar. Color of all other Spinners in the app should stay intact.

I tried following.

styles.xml

<style name="SpinnerOnPrimaryStyle" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:spinnerItemStyle">@style/mySpinnerItemStyle</item>
</style>

<style name="mySpinnerItemStyle" parent="android:Widget.TextView.SpinnerItem">
    <item name="android:textColor">@color/text_on_primary</item>
</style>

Toolbar

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_actionbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/tab_background"
    android:gravity="center_vertical"
    app:theme="@style/ToolBarStyle">

    <Spinner
        android:id="@+id/categorySpinner"
        app:theme="@style/SpinnerOnPrimaryStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp" />

</android.support.v7.widget.Toolbar>

But, the color of the Spinner doesn't change.

If I set android:spinnerItemStyle of my base theme to mySpinnerItemStyle, the Spinner color gets changed. But this cahnges the color of all Spinners in the app, which I don't want to happen.

(Following app theme changes spinner color, but it changes color of all spinners)

<!-- Application theme. -->
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    <item name="android:spinnerItemStyle">@style/mySpinnerItemStyle</item>
</style>

How can I change the color of only the Spinner in the Toolbar? It would be better if I could do this in the theme alone, without going to do it programmatically.

Upvotes: 2

Views: 981

Answers (1)

azizbekian
azizbekian

Reputation: 62189

It seems to me, that as a layout to your Spinner items you are using one of those, that framework provides, i.e. android.R.layout.simple_spinner_item.

If you take a look at the source code, you'll notice, that it applies style="?android:attr/spinnerItemStyle" to it's content view. This means, that when you are initializing your adapter in activity/fragment, spinnerItemStyle would be the one that has been applied to your activity theme, and not the one that you had explicitly applied in xml:

ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, list);

You are left with two options.

First option

Duplicate that layout content, applying the style you wish:

my_spinner_item.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@android:id/text1"
          style="@style/MySpinnerItemStyle"
          android:singleLine="true"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:ellipsize="marquee"
          android:textAlignment="inherit"/>

When initializing adapter:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.my_spinner_item, list);

Second option

Pass a ContextThemeWrapper with appropriate theme applied to the constructor of ArrayAdapter.

styles.xml

<style name="MySpinnerTheme" parent="AppTheme">
    <item name="android:spinnerItemStyle">@style/MySpinnerItemStyle</item>
</style>

When initializing adapter:

Context wrappedContext = new ContextThemeWrapper(this, R.style.MySpinnerTheme);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(wrappedContext, android.R.layout.simple_spinner_item, list);

Upvotes: 4

Related Questions