package com.devsourcenter.customspinner.model;
import android.content.Context;
/**
* Interface to manage the color and the value of the Spinner
*/
public interface IEnumSpinner {
/**
* Get the localized value of the Spinner
*
* @param context Context
* @return The value of the Spinner
*/
public String getLabel(Context context);
/**
* Get the color of the selected value
*
* @return The integer representation of the color
*/
public int getColor();
}
Now we have to implement the interface in our Enum:
package com.devsourcenter.customspinner.model.enums;
import android.content.Context;
import android.graphics.Color;
import com.devsourcenter.customspinner.AppResources;
import com.devsourcenter.customspinner.R;
import com.devsourcenter.customspinner.model.IEnumSpinner;
/**
* This Enum is used to represent a color
*/
public enum ColorEnum implements IEnumSpinner {
RED(R.string.label_red),
BLUE(R.string.label_blue),
GREEN(R.string.label_green);
/**
* localized label key
*/
private int key;
private ColorEnum (int key) {
this.key = key;
}
// we override toString() in order to translate the labels in the drop-down
// list
@Override
public String toString() {
return AppResources.getContext().getString(key);
}
public String getLabel(Context context) {
return context.getResources().getString(key);
}
public int getColor() {
switch (this) {
case RED:
return Color.rgb(255, 0, 0);
case BLUE:
return Color.rgb(0, 0, 255);
case GREEN:
return Color.rgb(0, 255, 0);
}
return -1;
}
}
We need to implement an Application class to get the context in the
toString() method of ColorEnum. In addition we also add the attribute android:name="AppResources" in the AndroidManifest.xml under the tag Application, in order to instantiate the class when the process for the application is created.package com.devsourcenter.customspinner;
import android.app.Application;
import android.content.Context;
/**
* Class used to get a context in any part of the app
*/
public class AppResources extends Application {
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getContext() {
return mContext;
}
}
At this point we can implement the Adapter associated to the the Spinner. The holder pattern is used to increase performance:
package com.devsourcenter.customspinner.model.adapter;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.devsourcenter.customspinner.R;
import com.devsourcenter.customspinner.model.IEnumSpinner;
/**
* Adapter to fill Spinner with items
*/
public class EnumAdapter extends ArrayAdapter<IEnumSpinner> {
Context mContext;
int mLayoutResourceId;
IEnumSpinner[] mItems;
public EnumAdapter(Context context, int layoutResourceId,
IEnumSpinner[] data) {
super(context, layoutResourceId, data);
this.mLayoutResourceId = layoutResourceId;
this.mContext = context;
this.mItems = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
Holder holder;
if (row == null) {
// at this point we inflate the view with our custom layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(mLayoutResourceId, parent, false);
holder = new Holder();
holder.txtTitle = (TextView) row
.findViewById(R.id.textView_spinner);
row.setTag(holder);
} else {
holder = (Holder) row.getTag();
}
IEnumSpinner item = mItems[position];
holder.txtTitle.setText(item.getLabel(mContext));
holder.txtTitle.setTextColor(item.getColor());
return row;
}
static class Holder {
TextView txtTitle;
}
}
Finally we can create the Activity to include the Spinner:
package com.devsourcenter.customspinner;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Toast;
import com.devsourcenter.customspinner.model.adapter.EnumAdapter;
import com.devsourcenter.customspinner.model.enums.ColorEnum;
public class MainActivity extends Activity {
private EnumAdapter mColorAdapter;
private Spinner mSpinnerColor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mColorAdapter = new EnumAdapter(this, R.layout.spinner_layout,
ColorEnum.values());
mSpinnerColor = (Spinner) findViewById(R.id.spinner_color);
mSpinnerColor.setAdapter(mColorAdapter);
mSpinnerColor
.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
// get the enum selected
ColorEnum color = (ColorEnum) parent
.getItemAtPosition(position);
Toast.makeText(MainActivity.this,
color.getLabel(MainActivity.this),
Toast.LENGTH_LONG).show();
// do whatever you want
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}
We used this simple layout for the Activity (activity_main.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.devsourcenter.customspinner.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@string/label_choose"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Spinner
android:id="@+id/spinner_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
And this is the layout for the Spinner (spinner_layout.xml):
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView_spinner"
android:textAppearance="?android:attr/textAppearanceLarge"
android:padding="7dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TextView>
We also provided translated enum labels for English:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">CustomSpinner</string>
<string name="label_choose">Choose a color:</string>
<string name="label_red">Red</string>
<string name="label_blue">Blue</string>
<string name="label_green">Green</string>
</resources>
Italian:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label_red">Rosso</string>
<string name="label_blue">Blu</string>
<string name="label_green">Verde</string>
</resources>
and French:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label_red">Rouge</string>
<string name="label_blue">Bleu</string>
<string name="label_green">Vert</string>
</resources>
Here is the result:
So you can simply define your Enum and your spinner_layout.xml to customize a Spinner.

