ZetCode

Android Spinner 小部件

最后修改于 2012 年 10 月 29 日

在本章 Android 开发教程中,我们将介绍 Spinner 小部件。

Spinner 小部件允许用户从一系列选项中选择一个项目。在正常状态下,它显示当前选定的项目。点击 Spinner 小部件会显示一个下拉菜单,其中包含所有可用的项目。用户可以从列表中选择一个新的项目。Spinner 类用于创建 Spinner 小部件。

Spinner 小部件可以在 XML 文件中填充。或者可以以编程方式填充。在后一种情况下,我们需要一个 Adapter 类来填充 Spinner 小部件。Adapter 是 Spinner 和其数据之间的桥梁。

Spinner I

在第一个示例中,我们有一个 Spinner 小部件,其项目在 XML 文件中定义。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zetcode.finish"
      android:versionCode="1"
      android:versionName="1.0">
 <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
    <activity android:name="MainActivity"
                android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
 </application>
</manifest>

这是程序的清单文件。

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
   <Spinner
        android:id="@+id/spn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/dlangs"
        android:layout_marginTop="10dip"
        android:prompt="@string/spn_title" />

   <TextView
      android:id="@+id/tvId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" 
      android:layout_marginTop="10dip"
      />        
        
</LinearLayout>

main.xml 布局文件中,我们有一个 Spinner 和一个 TextViewandroid:entries="@array/dlangs" 属性定义了一个提供字符串数组的 XML 资源。字符串写在 strings.xml 文件中。

strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Spinner</string>
    <string name="spn_title">Choose a language</string>
    
    <string-array name="dlangs">
        <item>Python</item>
        <item>PHP</item>
        <item>Perl</item>
        <item>Tcl</item>
        <item>Ruby</item>
    </string-array>    
    
</resources>

strings.xml 文件中,我们有字符串数组的元素。这些在点击 Spinner 小部件时显示。

MainActivity.java
package com.zetcode.spinner;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;


public class MainActivity extends Activity implements OnItemSelectedListener 
{
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.tvId);

        Spinner spn = (Spinner) findViewById(R.id.spn);
        spn.setOnItemSelectedListener(this);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) 
    {
      String item = parent.getItemAtPosition(pos).toString();
      tv.setText(item);
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) 
    {      
      tv.setText("");
    }
}

Spinner 小部件中选择的项目显示在 TextView 小部件中。

public class MainActivity extends Activity implements OnItemSelectedListener 

MainActivity 类实现了 OnItemSelectedListener。该类现在必须实现两个方法:onItemSelected()onNothingSelected() 方法。

Spinner spn = (Spinner) findViewById(R.id.spn);
spn.setOnItemSelectedListener(this);

这两行获取对 Spinner 小部件的引用,并为其设置 OnItemSelectedListener

@Override
public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) 
{
    String item = parent.getItemAtPosition(pos).toString();
    tv.setText(item);
}

onItemSelected() 方法中,我们使用 getItemAtPosition() 获取当前选中的 Spinner 项目。该项目被转换为字符串并设置为 TextView

Spinner widget
图:Spinner 小部件

Spinner II

在第二个 Spinner 示例中,我们将以编程方式定义 Spinner 元素列表。为此,我们将使用 ArrayAdapter 结合 ArrayList

Adapter 设计模式被 Android 平台用于处理 Spinner 小部件。ArrayAdapter 是数据源和数据视图之间的中介。在这种情况下,数据源是 ArrayList,视图是 Spinner 小部件。使用 Adapter,我们可以解耦我们的代码。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zetcode.toast"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" 
            android:icon="@drawable/ic_launcher">
        <activity android:name="MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

这是清单文件。

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
  <Spinner
      android:id="@+id/spnId"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dip" 
      android:prompt="@string/spn_title" />    
      
  <TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dip"  />
    
</LinearLayout>

main.xml 文件中,我们有两个小部件:SpinnerTextView 小部件。这次我们没有为 Spinner 定义数组数据条目。

strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Spinner2</string>
    <string name="spn_title">Choose a language</string>
</resources>

这是 strings.xml 资源文件。

MainActivity.java
package com.zetcode.spinner2;

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

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;


public class MainActivity extends Activity implements OnItemSelectedListener
{
    private TextView tv;
    private Spinner spn;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setup();
    }

    public void setup()
    {
        tv = (TextView) findViewById(R.id.tvId);
   
        spn = (Spinner) findViewById(R.id.spnId);
        fillSpinner(spn);
        spn.setOnItemSelectedListener(this);
    }

    public void fillSpinner(Spinner spn) 
    {
        List<String> lst = new ArrayList<String>();
        lst.add("Python");
        lst.add("PHP");
        lst.add("Perl");
        lst.add("Tcl");
        lst.add("Ruby");
        
        ArrayAdapter<String> da = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, lst);
        da.setDropDownViewResource(android.R.layout.simple_spinner_item);

        spn.setAdapter(da);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) 
    {
      String item = parent.getItemAtPosition(pos).toString();
      tv.setText(item);
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) 
    {      
      tv.setText("");
    }
}

MainActivity.java 源文件中,我们用数据填充 Spinner 小部件并为该小部件实现 OnItemSelectedListener

spn = (Spinner) findViewById(R.id.spnId);
fillSpinner(spn);

我们获取对 Spinner 小部件的引用,并调用 fillSpinner() 方法来用数据填充它。

List<String> lst = new ArrayList<String>();
lst.add("Python");
lst.add("PHP");
lst.add("Perl");
lst.add("Tcl");
lst.add("Ruby");

创建一个 ArrayList 并用字符串填充。

ArrayAdapter<String> da = new ArrayAdapter<String>(this,
        android.R.layout.simple_spinner_item, lst);

创建 ArrayAdapter 的实例。它将 ArrayList 作为参数。

da.setDropDownViewResource(android.R.layout.simple_spinner_item);

此行确定 Spinner 小部件的下拉菜单的外观。这是一个没有单选按钮的下拉菜单。具有 android.R.layout.simple_spinner_dropdown_item 定义的 Spinner,其行中带有单选按钮。

spn.setAdapter(da);

Adapter 已为 Spinner 小部件设置。

Spinner dropdown menu
图:Spinner 下拉菜单

在本章 Android 开发教程中,我们写了关于 Spinner 小部件的内容。