I wanted to created a Spinner
which has the same look and feel as TextInputEditText
+ TextInputLayout
(with label and underline)
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:paddingTop="8dp"
>
<android.support.design.widget.TextInputEditText
android:id="@+id/nameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
/>
</android.support.design.widget.TextInputLayout>
TextView Label
First, we need to create a TextView
label which looks the same as the label created by TextInputLayout
.
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Category"
android:textColor="?android:textColorHint"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingBottom="8dp"
/>
For reusability, we can create a theme style for it. Edit res/values/styles.xml
<style name="TextView.InputLabel" parent="TextAppearance.AppCompat.Caption">
<item name="android:textColor">?android:textColorHint</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:paddingLeft">4dp</item>
<item name="android:paddingRight">4dp</item>
</style>
Apply style to TextView.
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Category"
style="@style/TextView.InputLabel"
/>
Spinner with Underline and same style as EditText (text size, color and padding)
Use @style/Widget.AppCompat.Spinner.Underlined
to add underline to Spinner.
<android.support.v7.widget.AppCompatSpinner
android:id="@+id/categorySpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dialog"
style="@style/Widget.AppCompat.Spinner.Underlined" />
The text size and padding might still differ slightly from EditText. We can edit those by editing the resource file used for ArrayAdapter.
We shall create res/layout/custom_simple_spinner_item
which is based on android.R.layout.simple_spinner_item
.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:paddingStart="0dp"
android:paddingLeft="0dp"
android:textSize="18sp"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textAlignment="inherit"/>
Apply the resource file when creating the ArrayAdapter
(Kotlin).
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, items)categorySpinner.adapter = adapter
NOTE: You will notice the bottom padding between text and underline is slightly larger than EditText, but I have yet to find a solution for this.
If you want spinner to look exactly like EditText without the right arrow/caret, set the background to R.drawable.abc_edit_text_material
.
categorySpinner.background = ContextCompat.getDrawable(this, R.drawable.abc_edit_text_material)
NOTE: This will solve the padding problem between text and underline (but without the right arrow/caret).
NOTE: This will introduce additional top padding between Spinner and TextView Label. To solve this, remove the TextView's bottom padding.
If you want to change the color of Spinner's underline, use setBackgroundTintList
.
val colorStateList = ContextCompat.getColorStateList(this, R.color.edit_text_readonly)ViewCompat.setBackgroundTintList(categorySpinner, colorStateList)
Put TextView Label and Spinner within a Layout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Category"
style="@style/TextView.InputLabel"
/>
<android.support.v7.widget.AppCompatSpinner
android:id="@+id/categorySpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dialog"
style="@style/Widget.AppCompat.Spinner.Underlined"
/>
</LinearLayout>