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;
}
}
}
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" />
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);
}
}