Diseño Android: Spinner (lista de opciones desplegable)

Última actualización: 12/02/2023
android

El componente Spinner de Android permite seleccionar un único elemento de los mostrados en una lista desplegable. Equivale al típico select de HTML, pero con una diferencia interesante: de serie, Spinner es capaz de mostrar la lista en un cuadro de diálogo.

En el presente tutorial veremos el uso básico de este componente, incluyendo la personalización del listado de opciones para que muestre iconos.

Importante. El elemento Spinner no está incluido en las guías de Material Design como tal. El mismo concepto se recoge bajo el nombre de Exposed dropdown menu y se implementa combinando los componentes TextInputLayout y MaterialAutoCompleteTextView. Si quieres cumplir estrictamente las especificaciones Material Design, te resultará más fácil conseguirlo con esos componentes que con Spinner.

Índice

  1. Proyecto de ejemplo
  2. Spinner básico
  3. Cuadro de diálogo
  4. Eventos
  5. Personalizar el diseño del Spinner
  6. Personalizar el estilo del texto
  7. Lista con iconos y texto
  8. Resultado final
  9. Proyecto de ejemplo

Proyecto de ejemplo

El proyecto de ejemplo usa las últimas versiones disponibles en febrero de 2023:

  • Android API 33
  • Android Studio Electric Eel
  • Gradle 7.5 (requiere Java 11)
  • Material Components 1.8

Con todo, ten en cuenta que Spinner es un View proporcionado por el sistema Android y no un componente gráfico disponible en una librería.

El lenguaje de programación es Java, pero el código que veamos será tan simple que no tendrás problemas en adaptarlo a Kotlin si prefieres este lenguaje.

Tenemos las dependencias de Material Components y ConstraintLayout:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2'
}

La aplicación cuenta con una sola activity con una Toolbar. La pantalla será un lienzo en el que añadiremos varios spinners para ensayar diversas funcionalidades.

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        >

           <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical">

        
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</LinearLayout>

En el fichero /res/values/themes.xml he declarado como tema global de la aplicación uno de tipo DayNight de Material Components. Son los que tienen soporte para tema claro y oscuro a la vez. En concreto, he seleccionado el que no se aplica a la ActionBar del sistema, ya que definimos nuestra propia Toolbar y le damos un estilo personalizado. Toda esta configuración se describe en el tutorial correspondiente. Por supuesto, eres libre de elegir el tema que más te convenga.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDark</item>
        <item name="toolbarStyle">@style/Widget.MaterialComponents.Toolbar.PrimarySurface</item>     
    </style>

</resources>

Spinner básico

Agreguemos a la pantalla nuestro primer Spinner:

    <TextView
        android:id="@+id/title_basic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/form_margin_top"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:text="@string/basic"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        />   

  <Spinner
        android:id="@+id/spinner_basic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/form_margin_top"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        app:layout_constraintTop_toBottomOf="@+id/title_basic"
        />

Muestra el Spinner y una etiqueta. Sin la lista de elementos a desplegar, el componente es inútil. La manera de proporcionar los valores de esa lista es con un ArrayAdapter. Si los valores son estáticos, puedes declararlos en los ficheros strings.xml. Tendrías algo así:

<string-array name="social_networks_array">
    <item>None</item>
    <item>Facebook</item>
    <item>Reddit</item>
    <item>Twitter</item>
    <item>Youtube</item>
</string-array>

Construimos el adapter y se lo pasamos al spinner:

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setupToolbar();
    setupSpinnerBasic();
  }

  private void setupSpinnerBasic() {
    Spinner spinner = findViewById(R.id.spinner_basic);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.social_networks_array, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
  }

El método ArrayAdapter#createFromResource devuelve un Adapter que contiene los valores definidos por social_networks_array. El layout que recibe este método es para el elemento seleccionado a mostrar sobre el mismo Spinner. Con setDropDownViewResource indicamos el layout para cada elemento de la lista. Ambos layouts ya están incluidos en Android; más adelante veremos cómo personalizarlos.

En la siguiente captura tienes el resultado.

El desplegable se posiciona encima del Spinner. Si no quieres que lo cubra, desactiva el flag overlapAnchor:

   <Spinner
        android:id="@+id/spinner_basic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/form_margin_top"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:overlapAnchor="false"
        app:layout_constraintTop_toBottomOf="@+id/title_basic"
        />

Mira ahora:

Puedes construir mediante código la lista para el desplegable:

 List<String> spinnerValues = List.of("value 1", "value 2", "value 3");
 ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, spinnerValues);

Dado que estamos ante un campo de un formulario, tendremos que acceder al valor seleccionado para leerlo y\o escribirlo:

//establece la posición del adapter seleccionada. Por omisión es la primera (0).
spinner.setSelection(3);
//obtiene la posición del adapter seleccionada
int posSelected = spinner.getSelectedItemPosition()

Conseguir que la lista se visualice en un cuadro de diálogo es muy sencillo, pues solo tienes que dar el valor «dialog» a la propiedad spinnerMode. Añadamos un nuevo Spinner con este comportamiento:

<Spinner
        android:id="@+id/spinner_prompt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/form_margin_top"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:spinnerMode="dialog"
        app:layout_constraintTop_toBottomOf="@+id/title_prompt"
        />

Con prompt se indica el título del diálogo:

 <Spinner
        android:id="@+id/spinner_prompt"        
        android:spinnerMode="dialog"
        android:prompt="@string/social"

Eventos

Recibimos los eventos de un Spinner en una implementación del listener AdapterView.OnItemSelectedListener:

    public interface OnItemSelectedListener {
 
        void onItemSelected(AdapterView<?> parent, View view, int position, long id);

        void onNothingSelected(AdapterView<?> parent);
    }

onItemSelected se ejecuta cuando se selecciona un elemento distinto del que ya estaba seleccionado; onNothingSelected cuando el elemento seleccionado pase a ser ninguno porque, por ejemplo, se eliminó del adapter.

Esta implementación muestra en un Toast el nuevo valor seleccionado:

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
      @Override
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        String selected = (String) spinner.getItemAtPosition(position);
        Toast.makeText(MainActivity.this, selected, Toast.LENGTH_SHORT).show();
      }

      @Override
      public void onNothingSelected(AdapterView<?> parent) {
      }
    });

Por ser Spinner un View, podrías asignarle un OnItemClickListener con setOnItemClickListener. No caigas en la tentación, es una funcionalidad no soportada tal y como puedes ver en el código de Spinner#setOnItemClickListener:

@Override
public void setOnItemClickListener(OnItemClickListener l) {
    throw new RuntimeException("setOnItemClickListener cannot be used with a spinner.");
}

Personalizar el diseño del Spinner

El diseño de un Spinner en sí mismo, sin el listado de opciones, es personalizable con un drawable de tipo selector que resuelva el diseño a aplicar en función del estado del componente. El selector puede basarse en imágenes de tipo 9-patch, imágenes editables con Android Studio cuyo tamaño se ajusta al de la vista.

Aquí tienes un selector genérico (/drawable/spinner_selector.xml):

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/btn_dropdown_normal" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="@drawable/btn_dropdown_disabled" android:state_enabled="false" />
    <item android:drawable="@drawable/btn_dropdown_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/btn_dropdown_selected" android:state_enabled="true" android:state_focused="true"/>
    <item android:drawable="@drawable/btn_dropdown_normal" android:state_enabled="true"/>
    <item android:drawable="@drawable/btn_dropdown_selected" android:state_focused="true"/>
    <item android:drawable="@drawable/btn_dropdown_normal"/>

</selector>

Las imágenes utilizadas en el fichero anterior son las siguientes:

btn_dropdown_disabled.9.pngbtn_dropdown_disabled.9
btn_dropdown_normal.9.pngbtn_dropdown_normal.9
btn_dropdown_pressed.9.pngbtn_dropdown_pressed.9
btn_dropdown_selected.9.pngbtn_dropdown_selected.9
Veamos cómo queda el estilo en un nuevo Spinner:
    <Spinner
        android:id="@+id/spinner_basic_background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/form_margin_top"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        app:layout_constraintTop_toBottomOf="@+id/title_basic_drawable"
        android:background="@drawable/spinner_selector"
        />

¡Puro vintage! Y es que este ejemplo lo escribí para la primera versión del tutorial publicada en 2015; toda una eternidad en el mundo de la programación. En aquel entonces ni siquiera existía Material Design.

Personalizar el estilo del texto

Ya hemos visto el uso básico del Spinner así como la configuración de su diseño. Veamos ahora cómo personalizar los estilos de los textos que muestra.

Primero, vamos con el elemento seleccionado. Este es el layout que estamos usando (android.R.layout.simple_spinner_item):

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1"
    style="?android:attr/spinnerItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:textAlignment="inherit"/>

Lo que haremos es crear nuestro propio layout (/res/layout/textview_spinner_selected.xml) tomando el anterior como referencia:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:textStyle="bold"
    android:textAlignment="inherit"/>

Es casi el mismo, solo pone la letra en negrita. En cualquier caso, lo fundamental es que respete el identificador del TextView porque es el que espera el Spinner.

Lo usamos como parámetro en la construcción del adapter:

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.social_networks_array, R.layout.textview_spinner_selected);

Vamos con el layout de la lista desplegable (android.R.layout.simple_spinner_dropdown_item) que estamos aplicando:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/dropdownListPreferredItemHeight"
    android:ellipsize="marquee"/>

De nuevo, lo copiamos y creamos un layout según nuestras necesidades. El siguiente introduce un relleno a ambos lados y aumenta la altura:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:layout_width="match_parent"
    android:ellipsize="marquee"
    android:layout_height="@dimen/list_height"    
    android:paddingStart="@dimen/list_padding"
    android:paddingEnd="@dimen/list_padding"
    android:singleLine="true" />

Lo aplicamos al adapter con setDropDownViewResource:

adapter.setDropDownViewResource(R.layout.textview_dropdown_spinner);

Esta imagen muestra un Spinner con android.R.layout.simple_spinner_dropdown_item (izquierda) y otro con R.layout.textview_dropdown_spinner (derecha).

En ambos casos, la alternativa a la definición de un nuevo layout consiste en crear estilos y aplicarlos a todos los spinners de nuestra aplicación. Presta atención:

<resources>

    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDark</item>
        <item name="toolbarStyle">@style/Widget.MaterialComponents.Toolbar.PrimarySurface</item>
        <item name="android:spinnerItemStyle">@style/AppTheme.SpinnerItem</item>
        <item name="android:spinnerDropDownItemStyle">@style/AppTheme.DropDownItem</item>
    </style>

    <style name="AppTheme.SpinnerItem" parent="@android:style/Widget.TextView.SpinnerItem">
        <item name="android:textStyle">bold</item>
    </style>

    <style name="AppTheme.DropDownItem" parent="@android:style/Widget.DropDownItem">
        <item name="android:layout_height">@dimen/list_height</item>
        <item name="android:paddingStart">@dimen/list_padding</item>
        <item name="android:paddingEnd">@dimen/list_padding</item>
    </style>

</resources>

En la línea 7 se declara el estilo predeterminado para el TextView correspondiente al elemento seleccionado de cualquier Spinner de la app. La línea 8 hace lo mismo para los elementos del listado. Como puedes ver, esos estilos heredan de los originales de Android para personalizar algunas de sus características.

Lista con iconos y texto

Aunque la lista desplegable es útil y funcional, resulta un poco «sosa». ¿Y si añadimos un icono a cada elemento? No solo será más vistosa, sino que además facilitaremos su empleo. El inconveniente es que se requiere cierto trabajo, pero no te preocupes porque voy a darte la «receta»:

1-. Crear el layout de la fila del desplegable (/res/layout/social_network_item.xml):

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:paddingTop="@dimen/list_icon_padding_top"
    android:paddingBottom="@dimen/list_icon_padding_top"
    android:background="?android:attr/selectableItemBackground"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageViewIcon"
        android:layout_width="@dimen/icon_width"
        android:layout_height="@dimen/icon_height"
        android:layout_marginStart="@dimen/list_icon_padding_side"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textViewLabel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Widget.TextView.SpinnerItem"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginStart="@dimen/list_icon_padding_side"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/imageViewIcon"
        app:layout_constraintTop_toTopOf="parent"
         />

</androidx.constraintlayout.widget.ConstraintLayout>

2-.Crear el layout del elemento seleccionado que se muestra sobre el Spinner. En el ejemplo (/res/layout/social_network_selected_item.xml) es una pequeña variación del anterior:

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageViewIcon"
        android:layout_width="@dimen/icon_width_selected"
        android:layout_height="@dimen/icon_height_selected"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textViewLabel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginStart="@dimen/list_icon_padding_side"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/imageViewIcon"
        app:layout_constraintTop_toTopOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

3-. La lista con los valores del desplegable consta de objetos de este tipo:

package com.danielme.android.spinner;

public class SocialNetwork {

  private final String name;
  private final int icon;

  public SocialNetwork(String name, int icon) {
    this.name = name;
    this.icon = icon;
  }

  public String getName() {
    return name;
  }

  public int getIcon() {
    return icon;
  }
  
}

4-. La «chicha» viene ahora: heredar de ArrayAdapter para sobrescribir un par de métodos. Vayamos paso a paso.

public class SocialNetworkSpinnerAdapter extends ArrayAdapter<SocialNetwork> {

El constructor de SocialNetworkSpinnerAdapter recibe y guarda la lista con todos los datos y el contexto. Invoca al constructor padre con el contexto y el layout del elemento seleccionado.

public class SocialNetworkSpinnerAdapter extends ArrayAdapter<SocialNetwork> {

  private Context context;
  private final List<SocialNetwork> items;

  public SocialNetworkSpinnerAdapter(Context context, List<SocialNetwork> items) {
    super(context, R.layout.social_network_selected_item, items);
    this.context = context;
    this.items = items;
  }

Hay que sobrescribir dos métodos. getView se invoca para rellenar el elemento seleccionado que aparece sobre el spinner; getDropDownView hace lo propio para los elementos del desplegable. Dado que la única diferencia entre ambos es el layout, voy a implementar la lógica en un único método:

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    return getView(position, convertView, parent, R.layout.social_network_selected_item);
  }

  @Override
  public View getDropDownView(int position, View convertView, ViewGroup parent) {
    return getView(position, convertView, parent, R.layout.social_network_item);
  }

El objeto convertView es la vista que contiene el elemento del Spinner que se está procesando en la llamada actual a getView. Debemos establecer en convertView los datos de la red social situada en la posición position de la lista:

  private View getView(int position, View convertView, ViewGroup parent, int layout) {
    View row = convertView;
    if (row == null) {
      row = inflate(parent, layout);
      createHolder(row);
    }
    setData(position, row);
    return row;
  }

  private View inflate(ViewGroup parent, int layout) {
    LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    return layoutInflater.inflate(layout, parent, false);
  }

  private void createViewHolder(View row) {
    SocialNetworkHolder redSocialHolder = new SocialNetworkHolder();
    redSocialHolder.icon = (row.findViewById(R.id.imageViewIcon));
    redSocialHolder.label = (row.findViewById(R.id.textViewLabel));
    row.setTag(redSocialHolder);
  }

  private void setData(int position, View row) {
    SocialNetwork redSocial = items.get(position);
    ((SocialNetworkHolder) row.getTag()).icon.setImageResource(redSocial.getIcon());
    ((SocialNetworkHolder) row.getTag()).label.setText(redSocial.getName());
  }

  private static class SocialNetworkViewHolder {

    ImageView icon;

    TextView label;

  }

El objeto convertView puede venir a null, por eso se «infla» cuando sea el caso (línea 4). Por motivos de eficiencia estoy aplicando el patrón «view holder» (literalmente, ‘contenedor de vista’). La idea es evitar recuperar los elementos gráficos del convertView (el icono y el texto) cada vez que los necesitemos.

Lo que propone el patrón es obtenerlos una primera vez, cuando se crea el convertView (método createViewHolder), y guardar sus referencias (clase SocialNetworkViewHolder) para que los sucesivos accesos sean más rápidos. Ese objeto SocialNetworkViewHolder vinculado a un convertView lo almacenamos en el propio convertView en su campo tag (línea 19). Así, cuando getView reciba un convertView que no sea nulo —la mayoría de las veces— no se pierde tiempo extrayendo su ImageView y TextView porque ya los tenemos en el SocialNetworkViewHolder del tag.

5-. El último paso es el más simple de todos: establecer el adapter en el spinner.

  private void setupSpinnerCustomAdapter() {
    Spinner spinner = findViewById(R.id.spinner_custom_adapter);
    spinner.setAdapter(new SocialNetworkSpinnerAdapter(this, buildSocialNetworksList()));
  }

  private List<SocialNetwork> buildSocialNetworksList() {
    return List.of(new SocialNetwork(getString(R.string.none), R.drawable.none),
            new SocialNetwork(getString(R.string.facebook), R.drawable.facebook),
            new SocialNetwork(getString(R.string.reddit), R.drawable.reddit),
            new SocialNetwork(getString(R.string.twitter), R.drawable.twitter),
            new SocialNetwork(getString(R.string.youtube), R.drawable.youtube)
    );
  }

Ha costado, pero el resultado es lindo 🥰

Android custom StringArray Spinner

¿Funcionará en un cuadro de diálogo? Ya sabes cómo comprobarlo con la opción android:spinnerMode=»dialog» (y prompt si quieres un título).

Resultado final

Proyecto de ejemplo

El proyecto se aloja en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.

9 comentarios sobre “Diseño Android: Spinner (lista de opciones desplegable)

  1. Bonito y util el spinner pero… ¿como posiciono el spinner en un elemento directamente?.

    Lo recupero de una tabla y quiero mostrar sus datos con spinner posicionado en ese dato.

    1. Puedes seleccionar programáticmente cuando quieras un elemento del spinner con el método setSelection proporcionando la posición que ocupa en la lista que le pasas al Adapter.

      En el ejemplo, con la siguiente sentencia se selecionaria Youtube:
      spinner.setSelection(14);

    1. Tendrás que ajustar el tamaño tanto de lo que se muestra sobre el botón en spinner_selecter_item.xml como del
      propio spinner directamente en el activity_main.xml y/o modifcar los 9-patch.

  2. Hola

    Con respecto a la propiedad «prompt» que mencionas al inicio de la explicación donde se especifica el titulo, una pregunta … Cómo puedo cambiar el color tanto del background y de la letra donde se despliga este titulo?

    Saludos & Gracias

  3. Eres el mejor enserio amigo gracias realmente no entendia lo que decias pero poco a poco fui entendiendo lo que nos estabas enseñando 🙂

  4. Siiiii, gracias lo amooo. Se ve super lindo 🙂 muy sencillo y con potencial. Que buen ejemplo para los que iniciamos.

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.