How do I make a Spinner's "disabled" state look disabled?
Asked Answered
I

14

30

When I disable my Spinner it looks almost exactly like it did prior to being disabled, i.e.

Before

enter image description here

After

enter image description here

It is disabled and so functionally everything is fine but I'd like it to look disabled. This question appears to have been asked around the traps (here and here for instance) but the closest anyone's come to an answer is this, which appears incomplete and I don't understand anyway?!?

Romain said it was to be fixed in Froyo onwards but I'm using Honeycomb and as you can see from the screenshots, it doesn't appear to work. Any advice would be appreciated.

Inconvenient answered 3/10, 2011 at 23:40 Comment(0)
P
45

Don't know if you still need this but there is a way. I've been struggling with this issue myself. I ended up doing something like this:

((Spinner) spinner).getSelectedView().setEnabled(false);
spinner.setEnabled(false);

What this actually does is disable the spinner and the selected item that is shown. Most likely the selected item is a TextView and it should show as a disabled TextView.

I am using this and it works. But for some reason unknown to me it is not as "greyed-out" as other disabled views. It still looks disabled though. Try it out.

Pigtail answered 1/2, 2012 at 9:41 Comment(4)
This didn't work for me, getSelectedView() returns null just after I call spinner.setSelection()Stevenstevena
@nobre: Do you set the spinner adapter before calling setSelection()? If not, even if you set the adapter afterwards and the spinner is populated, getSelectedView() will return nullPigtail
There's a Spinner attribute that appears to do the same thing now called disableChildrenWhenDisabled developer.android.com/reference/android/support/v7/mediarouter/…Ho
This isn't as a robust a solution as the answer below is and that one works as well, plus you don't have to specifically set the selected view disabled/enabled.Bozo
W
15

One clever way of making spinners look disabled is to lower the transparency.

Spinner spinner = (Spinner) findViewById(R.id.my_spinner);
spinner.setEnabled(false);
spinner.setAlpha(0.5f);
Wheal answered 12/6, 2017 at 21:45 Comment(0)
S
6

If you're creating an adapter with a custom layout (i.e., extending R.layout.simple_spinner_item), add this attribute to the XML: android:duplicateParentState="true"

Solander answered 17/12, 2014 at 20:30 Comment(0)
C
3
((Spinner) spnr).getSelectedView().setEnabled(false);
((Spinner) spnr).setEnabled(false);

spnr is my Spinner object which refers to the XML view file, by findViewById(...).

Convention answered 9/1, 2013 at 3:25 Comment(0)
D
3

The .getSelectedView() did not work for me. So I tricked the Spinner to show being disabled.

You will need to define your own colors for the disabled look.

For Example:

R.color.blue_text //means enabled
R.color.gray_text //means disabled

So to disable my spinner:

((TextView)mySpinner.getChildAt(0)).setTextColor(getResources().getColor(R.color.gray_text));
mySpinner.setEnabled(false);
mySpinner.setFocusable(false);

To enable my spinner:

((TextView)mySpinner.getChildAt(0)).setTextColor(getResources().getColor(R.color.blue_text));
mySpinner.setEnabled(true);
mySpinner.setFocusable(true);

You don't need to change styles or modify any XML. Just do this in your code, even within event methods, you should be fine.

Demonstrable answered 4/6, 2015 at 14:18 Comment(0)
E
2

I've tried the following, and it's working as expected for me:

_userMembership.setEnabled(false);
_userMembership.setClickable(false);
_userMembership.setAlpha((float)0.7);
_userMembership.setBackgroundColor(Color.GRAY);
Etheridge answered 13/11, 2017 at 21:28 Comment(0)
W
1

this worked for me... For disabling the spinner

your_spinner.getSelectedView();
your_spinner.setEnabled(false);

and enabling it back

your_spinner.setEnabled(true);
Wilcox answered 26/6, 2013 at 9:10 Comment(1)
You are missing a .setEnabled(false) in your first line.Alphorn
P
0

Views can be compose by multiple touchable elements. You have to disable them all, like this:

for(View lol : your_spinner.getTouchables() ) {
    lol.setEnabled(false);
}

If it is a simple one since it also returns itself:

Find and return all touchable views that are descendants of this view, possibly including this view if it is touchable itself.

View#getTouchables()

Politicize answered 17/10, 2013 at 16:12 Comment(0)
A
0

Mine may be a special case either due to the order that I'm setting my adapter or due to the fact that I'm using a two custom spinner classes:

  1. The first class extends the LinearLayout class, and
  2. The second extends the Spinner class.

The keys I found to getting the spinner to look disabled were:

  1. Invalidating the old object in the setEnabled function, and
  2. Setting the color in the onDraw function.

Inside both of those custom spinner classes, I have a special setEnabled function like this, invalidating the old view:

public void setEnabled(Boolean enabled) {
    super.setEnabled(enabled);
    invalidate();
}

I also override the onDraw function in my each custom spinner class:

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (this.getChildAt(0) != null) {
        this.getChildAt(0).setAlpha(this.isEnabled() ? 1.0f : 0.7f);
    }
}
Alphorn answered 3/12, 2014 at 17:14 Comment(0)
P
0

I had a similar problem, except getChildView returned null for me, so the excepted solution did not work. I believe this was caused because I set the adapter in XML, and this ignored the "clickable" and "enabled" attributes.

This was my XML:

<Spinner
android:id="@+id/my_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:alpha="0.86"
android:enabled="false"
android:clickable="false"
android:entries="@array/array_of_entries"
android:spinnerMode="dropdown"/>

The solution for me was to remove the "enabled" and "clickable" attributes and put the following code in my "onCreate"

spinner.setEnabled(false);

Hope it helps someone!

Paragraphia answered 8/11, 2015 at 10:45 Comment(0)
U
0

You can do without typecasting also as follows:

new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
             // Depend on your selection check position and disable it
             if(position == 1) {
                view.setEnabled(false);
                view.setEnabled(false);
             }
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {

    }
 }
Upcoming answered 4/11, 2016 at 8:8 Comment(0)
L
0

I found this to be the best solution to the same question that was previously answered by @JSPDeveloper01: https://mcmap.net/q/472371/-android-how-to-make-a-spinner-disabled-look-disabled

Since Android doesn't gray out the spinner when it has been set to disabled, he suggests creating a custom method that uses the .setAlpha command on the spinner, which grays out the text within it. Brilliant.

Leverage answered 12/2, 2018 at 16:42 Comment(0)
G
0

For future reference, if you're using Kotlin, you can make use of extension functions, and provide a custom behaviour for disabled elements:

fun Spinner.forceEnabled(isEnabled : Boolean){
    setEnabled(isEnabled)
    getChildAt(0)?.let{ childView ->
        childView.alpha = if (this.isEnabled) 1.0f else 0.33f
    }
    invalidate()
}

someSpinner.forceEnabled(true)

This will allow to set custom properties to spinner children views, as the spinner is being disabled, without need for subclassing. Be cautious, as extension functions are resolved statically!

Gusti answered 24/1, 2020 at 22:52 Comment(0)
S
0

I wrote a little Kotlin extension.

// android spinner enable/disable doesn't grey out the item.
// this does.
private fun AppCompatSpinner?.setEnabled(enable:Boolean) {
    if (this != null) {
        isEnabled = enable
        alpha = if (enable) 1.0f else 0.5f
    }
}
Spun answered 28/5, 2021 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.