Spinner & AutoCompleteTextView
Both Spinner and AutoCompleteTextView help a user pick from a list of values, but they suit different situations. RecipeBox uses one of each: a Spinner to filter recipes by category, and an AutoCompleteTextView to suggest ingredient names while typing.
Spinner: A Dropdown for a Fixed Set of Choices
A Spinner shows one selected value and, when tapped, opens a dropdown (or dialog) of the other options. RecipeBox's recipe list screen uses one to filter by category:
<Spinner
android:id="@+id/spCategoryFilter"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
The data can come from a string-array resource in res/values/arrays.xml:
<resources>
<string-array name="recipe_categories">
<item>Breakfast</item>
<item>Lunch</item>
<item>Dinner</item>
<item>Dessert</item>
</string-array>
</resources>
...or from a plain Java List<String> — either way, an ArrayAdapter<String> bridges the data to the Spinner:
Spinner spCategoryFilter = findViewById(R.id.spCategoryFilter);
ArrayAdapter<String> adapter = ArrayAdapter.createFromResource(
this, R.array.recipe_categories, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spCategoryFilter.setAdapter(adapter);
spCategoryFilter.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selectedCategory = (String) spCategoryFilter.getSelectedItem();
filterRecipesByCategory(selectedCategory);
}
@Override
public void onNothingSelected(AdapterView<?> parent) { }
});
- setAdapter() supplies the list of options the Spinner will display.
- getSelectedItem() reads back whichever value is currently chosen; it returns an Object, so cast it to String here.
- OnItemSelectedListener requires both methods implemented — unlike OnClickListener, it isn't a single-method functional interface if you also need onNothingSelected, so it's commonly left as an anonymous class rather than a lambda.
Building an ArrayAdapter From a Java List
If the categories come from a database instead of a fixed resource, build the adapter directly from a List<String>:
List<String> categories = recipeRepository.getAllCategoryNames();
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this, android.R.layout.simple_spinner_item, categories);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spCategoryFilter.setAdapter(adapter);
AutoCompleteTextView: Suggesting Matches While Typing
An AutoCompleteTextView is a regular editable text field that shows a dropdown of matching suggestions as the user types. RecipeBox uses one when adding an ingredient to a recipe, suggesting names from a list of previously used ingredients:
<AutoCompleteTextView
android:id="@+id/actvIngredient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Add an ingredient"
android:completionThreshold="1" />
AutoCompleteTextView actvIngredient = findViewById(R.id.actvIngredient);
String[] knownIngredients = { "Flour", "Sugar", "Eggs", "Butter", "Basil", "Garlic", "Onion" };
ArrayAdapter<String> ingredientAdapter = new ArrayAdapter<>(
this, android.R.layout.simple_list_item_1, knownIngredients);
actvIngredient.setAdapter(ingredientAdapter);
The Modern Material Alternative: ExposedDropdownMenu
Material Design's newer ExposedDropdownMenu pattern (a TextInputLayout wrapping a non-editable AutoCompleteTextView) gives you Spinner-like fixed-choice behavior but with Material's floating label, outlined box, and dropdown arrow styling. It's worth adopting once you're using Material Components throughout the app; see Material Components (Java) for the full setup.
Which One Should You Reach For?
| Widget | Best fit | RecipeBox example |
|---|---|---|
| Spinner | A small, fixed set of choices where the user picks exactly one | Category filter: Breakfast / Lunch / Dinner / Dessert |
| AutoCompleteTextView | Free text entry, with helpful suggestions pulled from a larger, possibly changing set | Ingredient name field, suggesting from previously used ingredients |