Material Spinner Example
A spinner is an android widget that basically displays items in dropdown. Thus allowing ussers to select only one item at a time.
The parent class of the inbuilt android spinner is the AbsSpinner, a an abstract adapterview.However, sometimes we are not so much attracted to the inbuilt or default spinner, due to functionality limitations or we just want something nicer.
In that case we can look at GitHub and obtain a third party library. Material Spinner is such library. It was first created by Jared Rumler more than 2 years ago. Since then it’s been receiving updates.
This library provides us an awesome spinner view for android. Here is the demo that will be created shortly:
MaterialSpinner Definition
MaterialSpinner is not built from the Spinner widget provided by android. Instead it’s a custom Spinner built from TextView.
First it belongs to the following package:
It’s a public class deriving from TextView:
Creating Material Spinner
MaterialSpinner provides three public contructors for programmatic creation:
No. | Contsructor |
---|---|
1. | public MaterialSpinner(Context context) {} |
2. | public MaterialSpinner(Context context, AttributeSet attrs) {} |
3. | public MaterialSpinner(Context context, AttributeSet attrs, int defStyleAttr) {} |
Internally, these contructors call a method called init()
where they pass their parameters to that method. It is the init()
method which then retrieves the default properties to be used from the resources. These properties include
- TextColor
- BackgroundColor
- HintColor
- PopupWindow Height dimensions etc
Furthermore a ListView gets instantiated inside this init() method among other things. It is this ListView that will be used to render the dropdown list of items.
Creation Via XML
You can also set the MaterialSpinner via XML layout:
<com.jaredrummler.materialspinner.MaterialSpinner
android_id="@+id/spinner"
android_layout_width="match_parent"
android_layout_height="wrap_content"/>
then reference it from the Code:
Populating the MaterialSpinner
MaterialSpinner, even though it derives from TextView, is a spinner, a custom one. Hence it renders collection of items in a dropdown list.
Normally with the default android spinner, you create an adapter explicitly to bind to your adapter.
However, MaterialSpinner is easier to use and saves you from this.
It internally maintains an adapter for you, a custom adapter called MaterialSpinnerAdapter.
That adapter is a child of BaseAdapter.
MaterialSpinner provides us with a public method called setItems()
which we overload with different parameter types.
No. | Method | Description |
---|---|---|
1. | public void setItems(@NonNull T… items) | Internally it calls the other setItems() method converting our passed array to a list and passing it as a parameter |
2. | public void setItems(@NonNull List items) | Passes this List to a MaterialSpinnerAdapter constructor. Then sets the adapter instance internally to the MaterialSpinner. |
Usage Example
Here’s an example:
Note you haven’t set any adapter explicitly.
Via Adapter
You can also use an adapter.
This can be a custom adapter by passing in a ListAdapter reference:
This will instantiate a MaterialSpinnerAdapterWrapper class, passing in your ListAdapter object. Then moving the MaterialSpinnerAdapterWrapper instance into setAdapterInternal
private method.
Or by passing a MaterialSpinnerAdapter instance into the setAdapter() method:
This will also pass that adapter into the setAdapterInternal()
method. The setAdapterInternal()
is a private method residing in the MaterialSpinner class with the following responsibilities:
- Set the the MaterialSpinnerAdapter instance it receieves as the adapter for our ListView. Note that the MaterialSpinnerAdapter itself is a child of BaseAdapter, so ListView can accept it.
- Check if the passed adapter has items in it. Then set the hint text, hint color and text color.
Listening To Selection Change Events
We can listen to selection change events for our spinner in a very easy manner:
mySpinner.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
@Override public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
Snackbar.make(view, "Clicked " + item, Snackbar.LENGTH_LONG).show();
}
});
Installing MaterialSpinner
This library can be installed in three ways depending on your build system and preferences:
-
Direct download of the Android Archive file.
-
Grabbing via Gradle:
-
Grab via Maven:
Material Spinner Example
Let’s now look at a material spinner example.
Questions this Example Answers
- Android Material Spinner Library and example.
- How to populate material spinner with an array of data.
- How to listen to selection events of material spinner.
Gradle Scripts
(a)Build.gradle
First we need to install Material Spinner by adding the following implementation statement in our app level build.gradle:
Resources
We will have two XML Layouts:
(a). activity_main.xml
Here’s our activity_main.xml. At the root we have a CoordinatorLayout.
Take note we are including the content_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context=".MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main"/>
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@drawable/ic_github_white_24dp"/>
</android.support.design.widget.CoordinatorLayout>
(b) content_main.xml
This is where we add our MaterialSpinner. At the root we have a RelativeLayout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context=".MainActivity"
tools_showIn="@layout/activity_main">
<com.jaredrummler.materialspinner.MaterialSpinner
android_id="@+id/spinner"
app_ms_dropdown_max_height="350dp"
app_ms_dropdown_height="wrap_content"
android_layout_width="match_parent"
android_layout_height="wrap_content"/>
</RelativeLayout>
Java Code
(a). MainActivity.java
This is our launcher and only activity. We will populate our MaterialSpinner with an array of strings.
First we are referencing our material spinner from our layout using findViewById()
method of the Activity class:
To fill our materialspinner with data we simply use the setItems()
method:
Then we also listen to the item selection events our Spinner:
spinner.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
@Override public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
Snackbar.make(view, "Clicked " + item, Snackbar.LENGTH_LONG).show();
}
});
spinner.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
@Override public void onNothingSelected(MaterialSpinner spinner) {
Snackbar.make(spinner, "Nothing selected", Snackbar.LENGTH_LONG).show();
}
});
Here’s the full code:
package com.jaredrummler.materialspinner.example;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.jaredrummler.materialspinner.MaterialSpinner;
public class MainActivity extends AppCompatActivity {
private static final String[] ANDROID_VERSIONS = {
"Cupcake",
"Donut",
"Eclair",
"Froyo",
"Gingerbread",
"Honeycomb",
"Ice Cream Sandwich",
"Jelly Bean",
"KitKat",
"Lollipop",
"Marshmallow",
"Nougat",
"Oreo"
};
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/jaredrummler/MaterialSpinner")));
} catch (ActivityNotFoundException ignored) {
}
}
});
MaterialSpinner spinner = (MaterialSpinner) findViewById(R.id.spinner);
spinner.setItems(ANDROID_VERSIONS);
spinner.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
@Override public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
Snackbar.make(view, "Clicked " + item, Snackbar.LENGTH_LONG).show();
}
});
spinner.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
@Override public void onNothingSelected(MaterialSpinner spinner) {
Snackbar.make(spinner, "Nothing selected", Snackbar.LENGTH_LONG).show();
}
});
}
}
Download
Also check our video tutorial it’s more detailed and explained in step by step.
No. | Location | Link |
---|---|---|
1. | GitHub | Direct Download |
2. | GitHub | Browse |
Credit to the Original Creator Jared Rumler
Example 2: Android MaterialSpinner with Floating Labels
Android MaterialSpinner Library and Example.
We will use a library created by @Ganfra called MaterialSpinner.
This is differnt from Jared Rumler’s MaterialSpinner.
MaterialSpinner(Ganfra’s) will provides us a Spinner with the Material style. You can use it like any regular Spinner.
It allows you to:
- Add floating label text
- Add hint and
- Add error messages.
Demo
Here’s the example demo we explore to learn how to use MaterialSpinner library.
Requirements
MaterialSpinner is used with android projects and requires at least API 14.
Installation
Android Studio uses the gradle as it’s build system.
Therefore we normally write gradle scripts to do several tasks related to our project. Such a task can be fetching a library as a dependency and adding it to our project.
So to add MaterialSpinner into your project, navigate over to the app-level(located in app folder of your project) and add the following under the dependencies closure:
[notice] If you use other libraries requiring appcompat-v7 like MaterialEditText make sure to exclude them if you have issue at compile time. [/notice. Check below.]
compile ('com.github.ganfra:material-spinner:2.0.0'){
exclude group: 'com.android.support', module: 'appcompat-v7'
}
How to use it
First you need to add it in your xml layout where you want it rendered:
You can see there are various options:
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner"
android_layout_width="match_parent"
android_layout_height="wrap_content"
app_ms_multiline="false"
app_ms_dropDownHintView="@layout/my_custom_dropdown_hint_item_layout"
app_ms_hintView="@layout/my_custom_hint_item_layout"
app_ms_hint="hint"
app_ms_enableFloatingLabel="false"
app_ms_enableErrorLabel="false"
app_ms_floatingLabelText="floating label"
app_ms_baseColor="@color/base"
app_ms_highlightColor="@color/highlight"
app_ms_errorColor="@color/error"
app_ms_typeface="typeface.ttf"
app_ms_thickness="2dp"
app_ms_hintColor="@color/hint"
app_ms_arrowColor="@color/arrow"
app_ms_arrowSize="16dp"
app_ms_alignLabels="false"
app_ms_floatingLabelColor="@color/floating_label"/>
MaterialSpinner allows you to set a hint and a floating label text so that suppose no floating label text is provided, the hint gets displayed.
Then in your java code you use it like a regular spinner with an adapter like ArrayAdapter:
String[] ITEMS = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, ITEMS);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner = (MaterialSpinner) findViewById(R.id.spinner);
spinner.setAdapter(adapter);
You can activate the error mode or deactivate:
Full MaterialSpinner Example
Let’s now look at a full material spinner example.
(a) hint_item.xml
We have a TextView as our root element.
<?xml version="1.0" encoding="utf-8"?>
<TextView
android_id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android_paddingLeft="0dp"
android_background="@color/spinner_hint_text_color"
android_singleLine="true"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_ellipsize="marquee"
android_textAlignment="inherit"/>
(b) dropdown_hint_item.xml
Also a TextView .
<?xml version="1.0" encoding="utf-8"?>
<TextView
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingLeft="40dp"
android_background="@android:color/darker_gray"
android_orientation="vertical" />
(c) activity_main.xml
This layout will be inflated into the main activity.
At the root we have a ScrollView. Inside it are several MaterialSpinner widgets arranged linearly and vertically and a button at the bottom.
<ScrollView
android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="vertical"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin">
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner1"
android_layout_width="match_parent"
android_layout_height="wrap_content"
app_ms_arrowColor="#0000FF"
app_ms_arrowSize="16dp"
app_ms_floatingLabelColor="#00FF00"
app_ms_floatingLabelText="floating label"
app_ms_hint="hint"
app_ms_multiline="true" />
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner2"
android_layout_width="match_parent"
android_layout_height="wrap_content"
app_ms_enableErrorLabel="false"
app_ms_enableFloatingLabel="false"
app_ms_hint="hint"
app_ms_hintColor="#0000FF" />
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner3"
android_layout_width="match_parent"
android_layout_height="wrap_content"
app_ms_enableErrorLabel="false"
app_ms_enableFloatingLabel="false" />
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner4"
android_layout_width="match_parent"
android_layout_height="wrap_content"
app_ms_alignLabels="false"
app_ms_baseColor="@color/spinner_base_color"
app_ms_multiline="false" />
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner5"
android_layout_width="match_parent"
android_layout_height="wrap_content" />
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner6"
android_layout_width="match_parent"
android_layout_height="wrap_content"
app_ms_enableErrorLabel="false"
app_ms_enableFloatingLabel="false"
app_ms_dropDownHintView="@layout/dropdown_hint_item"
app_ms_hintView="@layout/hint_item"
app_ms_hint="hint"
app_ms_hintColor="#0000FF" />
<fr.ganfra.materialspinner.MaterialSpinner
android_id="@+id/spinner7"
android_layout_width="match_parent"
android_layout_height="wrap_content" />
<Button
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_hint="Show/hide error"
android_onClick="activateError" />
</LinearLayout>
</ScrollView>
(b) MainActivity.java
This is the main activity and as class constants we have an error message as well as string array of items.
Then an ArrayAdapter and our spinner widgets as instance fields.
We will instantiate the ArrayAdapter and set invoke it’s setDropDownViewResource
method, passing in our dropdown view resource as android.R.layout.simple_spinner_dropdown_item
. setDropDownViewResource()
is a method responsible for Setting the layout resource to create the drop down views.
We then create several methods, each responsible for referencing a given MaterialSpinner and setting it’s adapter.
Here’s the full code:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import fr.ganfra.materialspinner.MaterialSpinner;
public class MainActivity extends AppCompatActivity {
private static final String ERROR_MSG = "Very very very long error message to get scrolling or multiline animation when the error button is clicked";
private static final String[] ITEMS = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"};
private ArrayAdapter<String> adapter;
MaterialSpinner spinner1;
MaterialSpinner spinner2;
MaterialSpinner spinner3;
MaterialSpinner spinner4;
MaterialSpinner spinner5;
MaterialSpinner spinner6;
MaterialSpinner spinner7;
private boolean shown = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, ITEMS);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
initSpinnerHintAndFloatingLabel();
initSpinnerOnlyHint();
initSpinnerNoHintNoFloatingLabel();
initSpinnerMultiline();
initSpinnerScrolling();
initSpinnerHintAndCustomHintView();
initEmptyArray();
}
private void initSpinnerHintAndCustomHintView() {
spinner6 = findViewById(R.id.spinner6);
spinner6.setAdapter(adapter);
spinner4.setHint("Select an item");
}
private void initSpinnerHintAndFloatingLabel() {
spinner1 = findViewById(R.id.spinner1);
spinner1.setAdapter(adapter);
spinner1.setPaddingSafe(0, 0, 0, 0);
}
private void initSpinnerOnlyHint() {
spinner2 = findViewById(R.id.spinner2);
}
private void initSpinnerNoHintNoFloatingLabel() {
spinner3 = findViewById(R.id.spinner3);
spinner3.setAdapter(adapter);
}
private void initSpinnerMultiline() {
spinner4 = findViewById(R.id.spinner4);
spinner4.setAdapter(adapter);
spinner4.setHint("Select an item");
}
private void initSpinnerScrolling() {
spinner5 = findViewById(R.id.spinner5);
spinner5.setAdapter(adapter);
spinner5.setHint("Select an item");
}
private void initEmptyArray() {
String[] emptyArray = {};
spinner7 = findViewById(R.id.spinner7);
spinner7.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, emptyArray));
}
public void activateError(View view) {
if (!shown) {
spinner4.setError(ERROR_MSG);
spinner5.setError(ERROR_MSG);
} else {
spinner4.setError(null);
spinner5.setError(null);
}
shown = !shown;
}
}
Download
Also check our video tutorial it’s more detailed and explained in step by step.
No. | Location | Link |
---|---|---|
1. | GitHub | Direct Download |
2. | GitHub | Browse |
Credit to the Original Creator Ganfra
How to Run
- Download the project.
- Go over to sample folder and edit import it to your android studio.Alternatively you can just copy paste the classes as well as the layouts and maybe other resources into your already created project.
- Then edit the app level build/gradle to add our dependency.