12.Spinner下拉列表
Spinner(下拉列表)提供了从一个数据集合中快速选择一项值的办法。
默认情况下Spinner显示的是当前选择的值,点击Spinner会弹出一个包含所有可选值的下拉菜单,从该菜单中可以为Spinner选择一个新值。
下拉列表的展示方式有两种:
一种是在当前下拉框的正下方展示列表,此时把spinnerMode属性设置为dropdown;
另一种是在页面中部以对话框形式展示列表,此时把SpinnerMode属性设置为dialog。
一、最简单的Spinner
首先新建一个SpinnerTest项目,并让Android Studio自动创建活动。
在布局文件中添加Spinner控件,修改activity_main.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Spinner android:id="@+id/spAnimals" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
1、通过android:entries属性添加数据
首先,修改strings.xml字符串资源文件,使用<string-array>元素来包含一些<item>子元素,用于定义生肖名称。代码如下:
<resources> …… <string-array name="list_animals"> <item>子鼠</item> <item>丑牛</item> <item>寅虎</item> <item>卯兔</item> <item>辰龙</item> <item>巳蛇</item> </string-array> </resources>
在字符串资源文件中,增加<string-array>节点,定义name为list_animals,在该节点下增加<item>项目节点。
然后,修改Spinner控件,增加android:entries属性,属性值为@array/list_animals:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Spinner android:id="@+id/spAnimals" android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@array/list_animals" /> </LinearLayout>
运行程序,效果如图显示:
2、通过适配器添加数据
首先,删除Spinner控件中的android:entries属性,再修改MainActivity中的代码,如下所示:
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private String[] animals = {"子鼠", "丑牛", "寅虎", "卯兔", "辰龙", "巳蛇", "午马", "未羊", "申猴", "酉鸡", "戌狗", "亥猪"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //声明一个下拉列表的数组适配器 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, animals); //从布局文件中获取名叫spAnimals的下拉框 Spinner spAnimals = findViewById(R.id.spAnimals); //设置下拉框的数组适配器 spAnimals.setAdapter(adapter); } }
这里使用的还是ArrayAdapter,和ListView用的ArrayAdapter一样。这里由于我们提供的数据都是字符串,因此将ArrayAdapter的泛型指定为String。
然后在ArrayAdapter的构造方法中依次传入当前上下文、Spinner子项布局的id,以及要适配的数据。
这里的Spinner子项布局的id是android.R.layout.simple_spinner_item(列表-间距紧凑不好看)。
内置的布局样式还有:
- android.R.layout.simple_spinner_dropdown_item:列表-间距较高比较好看
- android.R.layout.simple_list_item_single_choice:单选按钮
- android.R.layout.simple_list_item_checked:复选框-选中的有绿勾
android.R.layout.simple_spinner_item android.R.layout.simple_spinner_dropdown_item
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private String[] animals = {"子鼠", "丑牛", "寅虎", "卯兔", "辰龙", "巳蛇", "午马", "未羊", "申猴", "酉鸡", "戌狗", "亥猪"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //声明一个下拉列表的数组适配器 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, animals); // 设置下拉菜单展开时的样式 adapter.setDropDownViewResource(android.R.layout.simple_list_item_checked); //从布局文件中获取名叫spAnimals的下拉框 Spinner spAnimals = findViewById(R.id.spAnimals); //设置下拉框的数组适配器 spAnimals.setAdapter(adapter); } }
二、定制Spinner的界面
1、定制”未展开“和”展开“的样式
未展开样式item_select.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="45dp" android:background="@android:color/holo_blue_dark" android:gravity="center" android:textColor="@android:color/holo_red_light" android:textSize="14sp" />
展开样式item_dropdown.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="45dp" android:gravity="center" android:textColor="@android:color/black" android:textSize="14sp" />
修改布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Spinner android:id="@+id/spAnimals" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:background="@null" android:dropDownVerticalOffset="45dp" android:spinnerMode="dropdown" /> </LinearLayout>
修改MainActivity.java
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private String[] animals = {"子鼠", "丑牛", "寅虎", "卯兔", "辰龙", "巳蛇", "午马", "未羊", "申猴", "酉鸡", "戌狗", "亥猪"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //声明一个下拉列表的数组适配器 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item_select, animals); // 设置下拉菜单展开时的样式 adapter.setDropDownViewResource(R.layout.item_dropdown); //从布局文件中获取名叫spAnimals的下拉框 Spinner spAnimals = findViewById(R.id.spAnimals); //设置下拉框的数组适配器 spAnimals.setAdapter(adapter); } }
运行效果:
2、Spinner的其他方法
(1)设置下拉框的标题。
只在dialog样式中显示,android:spinnerMode="dialog",如左图;不在dropdown样式下显示,android:spinnerMode="dropdown",如右图。
- setPrompt(CharSequence prompt):参数为字符串
- setPromptId(int promptId):参数为字符串的ID,如R.string.xxxx
(2)设置下拉框默认的显示第n项,注意该方法要在setAdapter()方法之后调用
- setSelection(int position):
- setSelectionInt(int position, boolean animate) :
3、dropdown模式下的列表分割线
在下图①中的位置添加自己的style,在②处进行使用。themes.xml文件可能会提示错误,可能是Android Studio语法检查误判,关闭再打开就好了。
在style中添加如下代码即可,打开themes.xml文件。
添加样式:
<style name="XSpinnerStyle" parent="android:Widget.ListView.DropDown"> <!-- 分隔线颜色 --> <item name="android:divider">#3F51B5</item> <item name="android:dividerHeight">1dp</item> </style>
然后在AppTheme中调用:
<item name="android:dropDownListViewStyle">@style/XSpinnerStyle</item>
但注意,该分割线只有是dropdown样式时才会显示。运行结果:
三、实现选择项事件
调用setOnItemSelectedListener()方法来为Spinner绑定AdapterView.OnItemSelectedListener事件监听器,可以使用匿名类实现接口的方式。
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private String[] animals = {"子鼠", "丑牛", "寅虎", "卯兔", "辰龙", "巳蛇", "午马", "未羊", "申猴", "酉鸡", "戌狗", "亥猪"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //声明一个下拉列表的数组适配器 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item_select, animals); // 设置下拉菜单展开时的样式 adapter.setDropDownViewResource(R.layout.item_dropdown); //从布局文件中获取名叫spAnimals的下拉框 Spinner spAnimals = findViewById(R.id.spAnimals); //设置下拉框的标题。只在dialog样式中显示,android:spinnerMode="dialog";不在dropdown样式下显示,android:spinnerMode="dropdown"。 spAnimals.setPrompt("请选择你的生肖"); // 参数为字符串 // spAnimals.setPromptId(R.string.app_name); // 参数为字符串的ID,如R.string.xxxx //设置下拉框的数组适配器 spAnimals.setAdapter(adapter); //设置下拉框默认的显示第一项,注意,该方法要在setAdapter()方法之后调用 spAnimals.setSelection(1, true); //给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法 spAnimals.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // parent:为Spinner控件;view:显示文字的TextView;position:下拉选项的位置从0开始 Toast.makeText(MainActivity.this, "您选择的是:" + animals[position], Toast.LENGTH_SHORT).show(); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } }
运行结果: