Is there a way to add a footer inside a spinner drop down list? For instance, say I am populating a spinner from a database, but I want a selection at the bottom of the list regardless of how I arrange the list. The list might be “Database Item 1, 2.., 3…” and at the bottom of the list a footer choice of “Add Item to Database.”
So far I have used your CustomSpinner class as follows:
public class CustomSpinner extends Spinner implements OnItemClickListener {
private AlertDialog myDialog = null;
private OnClickListener myButtonClickListener = null;
private GrainSpinnerAdapter adapter = null;
public CustomSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setButtonClickListener(OnClickListener listener) {
myButtonClickListener = listener;
}
public void setAdapter(GrainSpinnerAdapter adapter){
this.adapter = adapter;
}
@Override
public boolean performClick() {
Context context = getContext();
//Inflate the layout
final LayoutInflater inflater = LayoutInflater.from(getContext());
final View v = inflater.inflate(R.layout.my_custom_spinner, null);
// set up list view
final ListView lv = (ListView) v.findViewById(R.id.list);
lv.setAdapter(adapter);
lv.setSelection(getSelectedItemPosition());
lv.setOnItemClickListener(this);
// set up button
final Button btn = (Button) v.findViewById(R.id.addButton);
btn.setOnClickListener(myButtonClickListener);
// build our dialog
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// show prompt, just as our Spinner parent does
if (getPrompt() != null) {
builder.setTitle(getPrompt());
}
// create and show dialog
myDialog = builder.setView(v).create();
myDialog.show();
return true;
}
@Override
public void onItemClick(AdapterView<?> view, View itemView, int position, long id) {
setSelection(position);
if (myDialog != null) {
myDialog.dismiss();
myDialog = null;
}
}
}
I am wanting to use a separate adapter such as this:
public class GrainListAdapter extends SimpleCursorAdapter {
private static final String DEFAULT_UNITS = "American";
private Button upButton;
private Context myContext;
private RecipeGrainActivity parentActivity;
private Button downButton;
private String units;
private double getLbs;
public GrainListAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
myContext = context;
parentActivity = (RecipeGrainActivity) myContext;
//Checks for metric pref.
SharedPreferences myPrefs = PreferenceManager.getDefaultSharedPreferences(context);
units = String.valueOf(myPrefs.getString(context.getString(R.string.pref_measurement), DEFAULT_UNITS));
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
int idColumn = cursor.getColumnIndex("_id");
final int getId = cursor.getInt(idColumn);
final double increment = 0.25;
UnitsConversions convert = new UnitsConversions();
int nameColumn = cursor.getColumnIndex("name");
String getName = cursor.getString(nameColumn);
TextView name = (TextView)view.findViewById(R.id.GrainName);
name.setText(getName);
int originColumn = cursor.getColumnIndex("origin");
String getOrigin = cursor.getString(originColumn);
TextView origin = (TextView)view.findViewById(R.id.GrainOrigin);
origin.setText(getOrigin);
if(units.equals("Metric")){
//Sets labels to metric.
String kilos = context.getResources().getString (R.string.kilograms);
TextView weightLabel = (TextView)view.findViewById(R.id.GrainLbsLabel);
weightLabel.setText(kilos);
}
}
@Override
public View newView(Context context, Cursor cursor, final ViewGroup parent) {
View view = View.inflate(context, R.layout.grain_list_item, null);
return view;
}
}
Which allows me to build a custom row for each listitem in the spinner. I was thinking I could set the adapter to the CustomSpinner using the customspinner.setadapter() within my activity. However, the ListView defined in the CustomSpinner class uses an adapter referenced within the class. How do I pass my adapter into the class so it can use it?
Here is how I had to add the custom item to my layout:
<com.bluelightuniverse.android.brewmobile.CustomSpinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/GrainNameSpinner"
android:layout_toRightOf="@id/GrainOriginSpinner"
android:layout_toLeftOf="@+id/AddGrainButton">
</com.bluelightuniverse.android.brewmobile.CustomSpinner>
I’ve been experimenting with making more complex views in Spinners’ dialogs.
To do what you’ve explained, I made a subclass of
Spinner. I examined the source of the Android Spinner and overrided theperformClickto do essentially what you want: populate your own dialog with a custom view.You’ll need my customSpinner.xml:
Of course, make that
android:texta string resource.More words on this: Just make a
CustomSpinnerin your activity’s layout as you need it and callsetButtonClickListener(probably near where you set the adapter) to add a callback for your button, that perhaps prompts the user to add or whatever you need. And of coursenotifyDataSetChanged()on your adapter after adding to the database. Everything that works on a Spinner should work exactly the same with this custom spinner.Side note (UPDATED): You will have to make sure your adapter’s list items have black text (ex:
android:textColor="@android:color/primary_text_light_nodisable")! I changed the XML above so it doesn’t require white background on items (which then makes item highlights not work).Code notes: Since the people who made Android decided to not make an easy way to customize spinner dialogs (hard-coded use of
AlertDialog.BuilderusingsetSingleChoiceItems()as well as a private class to “convert”SpinnerAdapters toListAdapters), I had to copy their entire inner class to get the desired effect. Also note they are bad documenters (seeDropDownAdapter.isEnabled/areAllItemsEnabledfor the laugh of the day!).