Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android change text color of items in spinner

I have a spinner where in certain conditions some options should not be selectable. I have the code to make items not selectable but it does not grey out text color to specify that the item is not selectable. How would I change the text color of the items in the spinner that should be disabled? Here is the code:

public class main extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PatchedSpinner pSpinner = (PatchedSpinner) findViewById(R.id.spinner2);
    ArrayList<String> testarray = new ArrayList<String>();
    testarray.add("item0");
    testarray.add("item1");
    testarray.add("item2");
    testarray.add("item3");

    ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, 
            android.R.layout.simple_spinner_dropdown_item, testarray) { 

        @Override
        public boolean isEnabled(int position) {
            return position != 1;
        }

        public boolean areAllItemsEnabled() { 
            return false; 
        } 
    };
    pSpinner.setAdapter(spinnerAdapter);
}

Below is the Custom Spinner Class used to create a spinner that is able to disable certain items in the spinner.

public class PatchedSpinner extends Spinner {

    public PatchedSpinner(Context context, AttributeSet attrs, int defStyle) { 
        super(context, attrs, defStyle); 
    } 

    public PatchedSpinner(Context context) { 
        super(context); 
    } 

    public PatchedSpinner(Context context, AttributeSet attrs) { 
        super(context, attrs); 
    }

    @Override 
    public boolean performClick() {
        // this line removed, we do not want to delegate the click to the spinner.
        // boolean handled = super.performClick(); 

        Context context = getContext();

        final DropDownAdapter adapter = new DropDownAdapter(getAdapter());

        CharSequence mPrompt = getPrompt();

        AlertDialog.Builder builder = new AlertDialog.Builder(context); 
        if (mPrompt != null) { 
            builder.setTitle(mPrompt); 
        } 
        builder.setSingleChoiceItems(adapter, getSelectedItemPosition(), this).show();

        return true; 
    }

    private static class DropDownAdapter implements ListAdapter, SpinnerAdapter { 
        private SpinnerAdapter mAdapter;

        public DropDownAdapter(SpinnerAdapter adapter) { 
            mAdapter = adapter; 
        }

        public int getCount() { 
            return mAdapter == null ? 0 : mAdapter.getCount(); 
        }

        public Object getItem(int position) { 
            return mAdapter == null ? null : mAdapter.getItem(position); 
        }

        public long getItemId(int position) { 
            return mAdapter == null ? -1 : mAdapter.getItemId(position); 
        }

        public View getView(int position, View convertView, ViewGroup parent) { 
            return getDropDownView(position, convertView, parent); 
        }

        public View getDropDownView(int position, View convertView,ViewGroup parent) { 
            if (mAdapter == null) {
                return null;
            }
            mAdapter.getDropDownView(position, convertView, parent);
        }

        public boolean hasStableIds() { 
            return mAdapter != null && mAdapter.hasStableIds(); 
        }

        public void registerDataSetObserver(DataSetObserver observer){ 
            if (mAdapter != null) { 
                mAdapter.registerDataSetObserver(observer); 
            } 
        }

        public void unregisterDataSetObserver(DataSetObserver observer) { 
            if (mAdapter != null) { 
                mAdapter.unregisterDataSetObserver(observer); 
            } 
        }

        // PATCHED 
        public boolean areAllItemsEnabled() { 
            if (mAdapter instanceof BaseAdapter) { 
                return ((BaseAdapter) mAdapter).areAllItemsEnabled(); 
            } else { 
                return true; 
            } 
        }

        // PATCHED 
        public boolean isEnabled(int position) { 
            if (mAdapter instanceof BaseAdapter) { 
                return ((BaseAdapter) mAdapter).isEnabled(position); 
            } else { 
                return true; 
            } 
        }

        public int getItemViewType(int position) { 
            return 0; 
        }

        public int getViewTypeCount() { 
            return 1; 
        }

        public boolean isEmpty() { 
            return getCount() == 0; 
        } 
    }
}
like image 833
Jonathan Avatar asked Apr 29 '11 19:04

Jonathan


People also ask

What is spinner How do you create spinner and its adapter explain with example?

Android Spinner is a view similar to the dropdown list which is used to select one option from the list of options. It provides an easy way to select one item from the list of items and it shows a dropdown list of all values when we click on it.


2 Answers

For anyone that wants to use the original provided android spinner.

public class main extends Activity { 

    private Spinner _spinnerMethod;

    String[] _methodStrings = new String[]{"Item A", "Item B:False","Item C:False","Last Item"};

    @Override 
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.main);     

        CreateSpinner();
    }

    public void CreateSpinner()
    {       
    _spinnerMethod = (Spinner) findViewById(R.id.spinner_edit_death_method);
    final ArrayList<String> reasonArray = new ArrayList<String>();
    for(int i = 0; i <_methodStrings.length;i ++)
    {
        reasonArray.add(_methodStrings[i]);
    }

    ArrayAdapter<String> methodAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, reasonArray)
        {

            @Override      
            public boolean isEnabled(int position) {
                String val = reasonArray.get(position);
                // In my case added :False to the end of strings I wanted effected for some call
                boolean isFalse = val.contains(":False");                   
                return !isFalse; 
            }

            @Override                
            public boolean areAllItemsEnabled() {
                return false;
            }

            @Override
            public View getDropDownView(int position, View convertView,android.view.ViewGroup parent){
                View v = convertView;
                if (v == null) {
                    Context mContext = this.getContext();
                    LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    // Androids orginal spinner view item
                    v = vi.inflate(android.R.layout.simple_spinner_dropdown_item, null);
                }
                // The text view of the spinner list view
                TextView tv = (TextView) v.findViewById(android.R.id.text1);
                String val = reasonArray.get(position); 
                // remove the extra text here
                tv.setText(val.replace(":False", ""));

                boolean disabled = !isEnabled(position);
                if(disabled){tv.setTextColor(Color.GRAY);}
                else{tv.setTextColor(Color.BLACK);}

                return v;  
            }
        };
    methodAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    _spinnerMethod.setAdapter(methodAdapter);
    }       
}
like image 182
SatanEnglish Avatar answered Oct 26 '22 21:10

SatanEnglish


I figured out that to make this work you have to override the getDropDownView when setting up the ArrayAdapter in the main activity.

public class main extends Activity {  
     @Override 
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.main);  

        PatchedSpinner pSpinner = (PatchedSpinner) findViewById(R.id.spinner2); 
        ArrayList<String> testarray = new ArrayList<String>();
        testarray.add("item0");
        testarray.add("item1");
        testarray.add("item2");
        testarray.add("item3");
        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item, testarray) {

           @Override      
           public boolean isEnabled(int position) {
               return position != 1;                             
           }

           @Override                
           public boolean areAllItemsEnabled() {
               return false;
           }

           @Override
           public View getDropDownView(int position, View convertView, ViewGroup parent){
               View v = convertView;
               if (v == null) {
                   Context mContext = this.getContext();
                   LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                   v = vi.inflate(R.layout.row, null);
               }

               TextView tv = (TextView) v.findViewById(R.id.spinnerTarget);
               tv.setText(testarray.get(position));

               switch (position) {
                   case 0:
                       tv.setTextColor(Color.RED);  
                       break; 
                   case 1:
                       tv.setTextColor(Color.BLUE);
                       break;
                   default:
                       tv.setTextColor(Color.BLACK);
                       break;
               }
               return v;  
           }              
        };

        pSpinner.setAdapter(spinnerAdapter); 
} 

The layout that is being inflated is a custom layout called row.xml. it is used to set the display for the dropdown view.

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/spinnerTarget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="14pt" />
like image 45
Jonathan Avatar answered Oct 26 '22 20:10

Jonathan