Android UI Spinner的使用

 

前言

  最近一直在讲AndroidUI的开发,今天讲一下Spinner控件,这是一个列表选择框,可以弹出一个列表供用户选择。在本片博客中,会讲解Spinner的基本属性以及设置之后的效果,以及使用SimpleAdapter绑定自定义格式的数据到Spinner中。

Spinner

  Spinner是一个列表选择框,会在用户选择后,展示一个列表供用户进行选择。Spinner是ViewGroup的间接子类,它和其他的Android控件一样,数据需要使用Adapter进行封装。

  下面介绍一下Spinner的常用XML属性,Android也为其属性提供了相应的getter、setter方法:

  • android:spinnerMode:列表显示的模式,有两个选择,为弹出列表(dialog)以及下拉列表(dropdown),如果不特别设置,为下拉列表。。
  • android:entries:使用<string-array.../>资源配置数据源。
  • android:prompt:对当前下拉列表设置标题,仅在dialog模式下有效。传递一个“@string/name”资源,需要在需要在资源文件中定义<string.../>。

  作为一个列表选择控件,Spinner具有一些选中选项可以触发的事件,但它本身没有定义这些事件,均继承自间接父类AdapterView。Spinner支持的几个常用事件有以下几个:

  • AdapterView.OnItemCLickListener:列表项被点击时触发。
  • AdapterView.OnItemLongClickListener:列表项被长按时触发。
  • AdapterView.OnItemSelectedListener:列表项被选择时触发。

  PS:因为适配器可以设置各种不同的样式,有选择、单选、多选,所以OnItemCLickListener和OnItemSelectedListener是适用于不同场景的。

Spinner的数据绑定

  对于Spinner展示的数据源,一般使用两种方式设定数据:

  • 通过XML资源文件设置,这种方式比较死板,但是如果仅仅需要展示固定的、简单的数据,这种方式还是可以考虑的,比较直观。
  • 使用Adapter接口设置,这是最常见的方式,动态、灵活,可以设定各种样式以及数据来源。

  先来讲讲通过XML资源文件设置Spinner数据的方式,首先需要在/res/values目录下新建XML格式的资源文件,名字不重要,但是一般会使用strings.xml。在其中的<resourse.../>标签下,定义<string-array.../>标签,通过它中的<item.../>标签来设置选择数据。

  XML文件结构:

  <resource>

    <string-array name="arrayname">

      <item>item1</item>

      <item>item2</item>

      <item>item3</item>

    </string-array>

  <resource>

  通过适配器Adapter可以设定比较复杂的展示效果,一般项目中比较常用的也是这种方式。但是如果对于动态的、简单的数据,可以使用ArrayAdapter对象来设置适配器,关于ArrayAdapter类的介绍,在我的另外一篇博客中有介绍,不了解的朋友可以先看看:Android--UI之AutoCompleteTextView 

  下面通过一个示例,讲解一下上面说的属性、事件,以及使用ArrayAdapter和XML资源文件设定简单数据,代码中注释已经说的很清楚了,这里就不再累述了。

  布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical" >
  
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
         android:text="弹出的Spinner" />
      <Spinner
         android:id="@+id/spinnerBase"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:spinnerMode="dialog" />
 
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="下拉的Spinner(默认)" />
      
     <Spinner
         android:id="@+id/spinnerBase1"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:spinnerMode="dropdown" />
 
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="entries绑定数据源" />
 
     <Spinner
         android:id="@+id/spinnerBase2"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/beijing" />
 
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="弹出带标题的Dialog,并且使用entries绑定数据源" />
 
     <Spinner
         android:id="@+id/spinnerBase3"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/beijing"
         android:prompt="@string/beij_prompt"
         android:spinnerMode="dialog" />
 
 </LinearLayout>

 

实现代码:

package com.example.androidspinnertest;

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

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

public class MainActivity extends Activity {

 private Spinner spinner1,spinner2;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  spinner1=(Spinner)findViewById(R.id.spinnerBase);
  spinner2=(Spinner)findViewById(R.id.spinnerBase1);
  
  ArrayAdapter<String> adapter=new ArrayAdapter<String>(
    MainActivity.this,android.R.layout.simple_spinner_item,getData());
  spinner1.setAdapter(adapter);
  spinner2.setAdapter(adapter);
  
  spinner1.setOnItemSelectedListener(new OnItemSelectedListener(){

   @Override
   public void onItemSelected(AdapterView<?> arg0, View arg1,
     int arg2, long arg3) {
    // TODO Auto-generated method stub
    Toast.makeText(MainActivity.this, arg0.getItemAtPosition(arg2).toString(), Toast.LENGTH_SHORT).show();
   }

   @Override
   public void onNothingSelected(AdapterView<?> arg0) {
    // TODO Auto-generated method stub
    
   }
   
  });
 }

 private List<String> getData() {
  // TODO Auto-generated method stub
  List<String> datalist=new ArrayList<String>();
  datalist.add("BeiJing");
  datalist.add("ShangHai");
  datalist.add("NanJing");
  datalist.add("ChangSha");
  return datalist;
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

}

value XML资源文件:

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

    <string name="app_name">AndroidSpinnerTest</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="beij_prompt">北京区域</string> 
      <string-array name="beijing">
          <item>朝阳区</item>
          <item>海淀区</item>
         <item>房山区</item>
         <item>丰台区</item>
         <item>东城区</item>
         <item>西城区</item>
     </string-array>    
    
</resources>

 

SimpleAdapter配置Spinner数据

  对于一个稍复杂的数据,如果想对其展示,光使用ArrayAdapter是无法满足需求的,现在在另外介绍一个Adapter,SimpleAdapter,同样继承自Adapter。

  SimpleAdapter是一个简单的适配器,映射静态的XML格式的布局文件到视图中。可以指定一个List<Map<P,T>>格式的数据,List中的每一条数据对应一行,而Map中的每一条数据对应数据行的一列。这个数据用来映射到XML定义的布局控件中,对应关系通过构造函数的另外两个参数来指定,现在来介绍一下SimpleAdapter的构造函数。

  SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

  • context:上下文对象,没什么好说的,一般就是当前的Activity。
  • data:上面介绍的List<Map<S,T>>类型的数据。
  • resource:XML资源的Id,通过R对象选中。
  • from:一个String类型数组,每条数据对应data数据中,Map结构定义的Key。
  • to:一个int类型数组,对应XML资源中控件的ID,注意顺序必须与from中指定数据的顺序一致。

  下面通过一个示例讲解一下SimpleAdapter是如何设置自定义格式数据的。

  布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<Spinner android:id="@+id/spinnerAdapter" android:layout_width="match_parent"
    android:layout_height="wrap_content" />
</LinearLayout>

 

XML布局资源代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:paddingLeft="10dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
    android:layout_height="wrap_content"
        android:gravity="center_vertical" 
        android:paddingLeft="10dp"
        android:textColor="#000"
        android:textSize="16dp" />

</LinearLayout>

 

实现代码:

package com.example.androidadapterspinnertest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends Activity {
    private Spinner spinner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        spinner = (Spinner) findViewById(R.id.spinnerAdapter);
        //声明一个SimpleAdapter独享,设置数据与对应关系
        SimpleAdapter simpleAdapter = new SimpleAdapter(
                MainActivity.this, getData(), R.layout.spinner,
                new String[] { "ivLogo", "applicationName" }, new int[] {
                        R.id.imageview, R.id.textview });
        //绑定Adapter到Spinner中
        spinner.setAdapter(simpleAdapter);
        //Spinner被选中事件绑定。
        spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                    int position, long id) {
                //parent为一个Map结构的和数据
                Map<String, Object> map = (Map<String, Object>) parent
                        .getItemAtPosition(position);
                Toast.makeText(MainActivity.this,
                        map.get("applicationName").toString(),
                        Toast.LENGTH_SHORT).show();
            }

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

    public List<Map<String, Object>> getData() {
        //生成数据源
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        //每个Map结构为一条数据,key与Adapter中定义的String数组中定义的一一对应。
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("ivLogo", R.drawable.ia);
        map.put("applicationName", "表情1");
        list.add(map);
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("ivLogo", R.drawable.ib);
        map2.put("applicationName", "表情2");
        list.add(map2);
        Map<String, Object> map3 = new HashMap<String, Object>();
        map3.put("ivLogo", R.drawable.ic);
        map3.put("applicationName", "表情3");
        list.add(map3);
        return list;
    }
}

 

运行效果图:


 

源码下载

 

<参考于:http://www.cnblogs.com/plokmju/p/android_Spinner.html>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<reference : http://www.cnblogs.com/plokmju/p/android_Spinner.html>

posted @ 2013-09-20 16:27  MMLoveMeMM  阅读(273)  评论(0)    收藏  举报