When I disable my Spinner it looks almost exactly like it did prior to being disabled, i.e.
Before
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()
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!
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:
LinearLayout
class, and Spinner
class.The keys I found to getting the spinner to look disabled were:
setEnabled
function, andonDraw
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);
}
}
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.
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) {
}
}
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"