Руководство Android Spinner

View more Tutorials:

1- Android Spinner

В Android, Spinner это  ViewGroup позволяющий пользователю выбрать значение из списка значений. В режиме по умолчанию, Android Spinner работает как  Dropdown List (Выпадающий список) или  Combox в других языках программирования.
Когда пользователь нажимает на  Android Spinner, выпадает список, содержащий все значения, и пользователь может выбрать одно значение.
Android Spinner имеет 2 режима (mode) с абсолютно разными интерфейсами:
  1. android:spinnerMode="dropdown"
  2. android:spinnerMode="dialog"

android:spinnerMode="dropdown"

Когда пользователь кликает (click) на  Spinner отображается  Dropdown List (выпадающий список), чтобы пользователь смог выбрать одно значение. Это режим по умолчанию у  Spinner.
android:spinnerMode="dropdown"

android:spinnerMode="dialog"

Когда пользователь кликает (click) на Spinner отображается  Dialog содержащий список значений, чтобы пользователь выбрал одно значение.
android:spinnerMode="dialog"

2- Пример: Spinner + ArrayAdapter

OK, теперь мы начнем с простым примером, используя  Spinner и ArrayAdapter. В данном примере,  Spinner будет содержать список объектов  Employee:
Adapter помогает вам сочетать  Spinner-Item Layout Resource и данные, чтобы создать  Spinner.
ArrayAdapter это готовый класс в библиотеке  Android. он является простым  Adapter, принимающий простой  Spinner-Item Layout Resource, включая  TextView, и может добавить  CheckBox, ImageView,..
Например: Простой  Spinner-Item Layout Resource с ID это  android.R.layout.simple_spinner_item уже определенный в  Android SDK и вы можете его использовать. Android Studio разрешает вам смотреть содержание данных файлов, нужно только держать клавишу  CONTROL и кликнуть на него, как в изображении ниже:
На  Android Studio создайте новый project:
  • File > New > New Project > Empty Activity
    • Name: SpinnerExample
    • Package name: org.o7planning.spinnerexample
    • Language: Java
activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:text="Select Employee:" />

        <Space
            android:layout_width="10dp"
            android:layout_height="wrap_content"
            android:layout_weight="0" />

        <Spinner
            android:id="@+id/spinner_employee"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package org.o7planning.spinnerexample;

import android.os.Bundle;
import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private Spinner spinnerEmployee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.spinnerEmployee = (Spinner) findViewById(R.id.spinner_employee);

        Employee[] employees = EmployeeDataUtils.getEmployees();

        // (@resource) android.R.layout.simple_spinner_item:
        //   The resource ID for a layout file containing a TextView to use when instantiating views.
        //    (Layout for one ROW of Spinner)
        ArrayAdapter<Employee> adapter = new ArrayAdapter<Employee>(this,
                                              android.R.layout.simple_spinner_item,
                                              employees);

        // Layout for All ROWs of Spinner.  (Optional for ArrayAdapter).
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        this.spinnerEmployee.setAdapter(adapter);

        // When user select a List-Item.
        this.spinnerEmployee.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                onItemSelectedHandler(parent, view, position, id);
            }

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

            }
        });
    }


    private void onItemSelectedHandler(AdapterView<?> adapterView, View view, int position, long id) {
        Adapter adapter = adapterView.getAdapter();
        Employee employee = (Employee) adapter.getItem(position);

        Toast.makeText(getApplicationContext(), "Selected Employee: " + employee.getFullName() ,Toast.LENGTH_SHORT).show();
    }

}
Employee.java
package org.o7planning.spinnerexample;

public class Employee {

    private String firstName;
    private String lastName;
    private String position;
    private int salary;

    public Employee(String firstName, String lastName, String position, int salary) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.position = position;
        this.salary = salary;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public String getFullName()  {
        return this.firstName + " " + this.lastName;
    }

    // Text show in Spinner
    @Override
    public String toString()  {
        return this.getFullName() + " - (" + this.position+")";
    }
}
 
EmployeeDataUtils.java
package org.o7planning.spinnerexample;

public class EmployeeDataUtils {

    public static Employee[] getEmployees()  {
        Employee emp1 = new Employee("James", "Smith", "Receptionist", 1000);
        Employee emp2 = new Employee("Michael", "Garcia", "CEO", 50000);
        Employee emp3 = new Employee("Robert", "Johnson", "Professional staff", 2000);

        return new Employee[] {emp1, emp2, emp3};
    }
}

3- Пример: Spinner + CustomAdapter

Кастомизирование  Adapter помогает вам получить  Spinner посложнее и красивее. Ниже является изображение иллюстрирующее  Spinner который содержить объекты  Language, и так же является нашим следующим примером, который мы выполним:
В данном примере мы создадим  "Spinner Item Layout Resource File", чтобы определить  Layout строки (row) у Spinner. CustomAdapter скомбинирукт данные и  "Spinner Item Layout Resource", чтобы создать  Spinner, который сможет увидеть пользователь.
OK. на  Android Studio создайте новый project:
  • File > New > New Project > Empty Activity
    • Name: CustomSpinnerAdapterExample
    • Package name: org.o7planning.customspinneradapterexample
    • Language: Java
Во-первых, нам нужно создать  Layout Resource File​​​​​​​, чтобы определить  Layout для  Spinner Item:
На  Android Studio, выберите файл  "layout", и выберите:
  • File > New > Layout Resource File
  • File Name: spinner_item_layout_resource.xml
  • Root element: LinearLayout
Дизайн интерфейса для  spinner_item_layout_resource:
spinner_item_layout_resource.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/textView_item_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Language Name" />

    <TextView
        android:id="@+id/textView_item_percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:text="Percent" />
</LinearLayout>
Главный интерфейс приложения:
activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:text="Select Language:"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Spinner
        android:id="@+id/spinner_language"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:spinnerMode="dialog"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package org.o7planning.customspinneradapterexample;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Spinner;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private Spinner spinner;
    private List<Language> languages;

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

        // Data:
        this.languages = LanguageDataUtils.getLanguages();


        this.spinner = (Spinner) this.findViewById(R.id.spinner_language);

        // Adapter"
        CustomAdapter adapter = new CustomAdapter(MainActivity.this,
                R.layout.spinner_item_layout_resource,
                R.id.textView_item_name,
                R.id.textView_item_percent,
                this.languages);

        this.spinner.setAdapter(adapter);
    }

}
 
CustomAdapter.java
package org.o7planning.customspinneradapterexample;

import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

public class CustomAdapter extends BaseAdapter  {

    private LayoutInflater flater;
    private List<Language> list;
    private int listItemLayoutResource;
    private int textViewItemNameId;
    private int textViewItemPercentId;


    // Arguments example:
    //  @listItemLayoutResource: R.layout.spinner_item_layout_resource
    //        (File: layout/spinner_item_layout_resource.xmll)
    //  @textViewItemNameId: R.id.textView_item_name
    //        (A TextVew in file layout/spinner_item_layout_resource.xmlxml)
    //  @textViewItemPercentId: R.id.textView_item_percent
    //        (A TextVew in file layout/spinner_item_layout_resource.xmll)
    public CustomAdapter(Activity context, int listItemLayoutResource,
                         int textViewItemNameId, int textViewItemPercentId,
                         List<Language> list) {
        this.listItemLayoutResource = listItemLayoutResource;

        this.textViewItemNameId = textViewItemNameId;
        this.textViewItemPercentId = textViewItemPercentId;
        this.list = list;
        this.flater = context.getLayoutInflater();
    }

    @Override
    public int getCount() {
        if(this.list == null)  {
            return 0;
        }
        return this.list.size();
    }

    @Override
    public Object getItem(int position) {
        return this.list.get(position);
    }

    @Override
    public long getItemId(int position) {
        Language language = (Language) this.getItem(position);
        return language.getId();
        // return position; (Return position if you need).
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Language language = (Language) getItem(position);

        // Example: @listItemLayoutResource: R.layout.spinner_item_layout_resource
        // (File: layout/spinner_item_layout_resourcerce.xml)
        View rowView = this.flater.inflate(this.listItemLayoutResource, null,true);

        // Example: @textViewItemNameId: R.id.textView_item_name
        // (A TextView in file layout/spinner_item_layout_resourcerce.xml)
        TextView textViewItemName = (TextView) rowView.findViewById(this.textViewItemNameId);
        textViewItemName.setText(language.getName());

        // Example: @textViewItemPercentId: R.id.textView_item_percent
        // (A TextView in file layout/spinner_item_layout_resource.xmlxml)
        TextView textViewItemPercent = (TextView) rowView.findViewById(textViewItemPercentId);
        textViewItemPercent.setText(language.getPercent() + "%");

        return rowView;
    }
}
Language.java
package org.o7planning.customspinneradapterexample;

public class Language {

    private long id;
    private String name;
    private float percent;

    public Language(long id, String name, float percent) {
        this.id = id;
        this.name = name;
        this.percent = percent;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getPercent() {
        return percent;
    }

    public void setPercent(float percent) {
        this.percent = percent;
    }
}
LanguageDataUtils.java
package org.o7planning.customspinneradapterexample;

import java.util.ArrayList;
import java.util.List;

public class LanguageDataUtils {

    public static List<Language> getLanguages( ) {
        Language javascript = new Language(1,"Javascript", 67.7f);
        Language htmlCss = new Language(2,"HTML/CSS", 63.1f);
        Language sql = new Language(3,"SQL", 54.7f);
        Language python = new Language(4,"Python", 44.1f);
        Language java = new Language(5, "Java", 40.2f);

        List<Language> list = new ArrayList<Language>();
        list.add(javascript);
        list.add(htmlCss);
        list.add(sql);
        list.add(python);
        list.add(java);

        return list;
    }
}

View more Tutorials: