zoukankan      html  css  js  c++  java
  • 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资源文件设定简单数据,代码中注释已经说的很清楚了,这里就不再累述了。

    布局代码:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" >
     6 
     7     <TextView
     8         android:layout_width="wrap_content"
     9         android:layout_height="wrap_content"
    10         android:text="弹出的Spinner" />
    11 
    12     <Spinner
    13         android:id="@+id/spinnerBase"
    14         android:layout_width="match_parent"
    15         android:layout_height="wrap_content"
    16         android:spinnerMode="dialog" />
    17 
    18     <TextView
    19         android:layout_width="wrap_content"
    20         android:layout_height="wrap_content"
    21         android:text="下拉的Spinner(默认)" />
    22 
    23     <Spinner
    24         android:id="@+id/spinnerBase1"
    25         android:layout_width="match_parent"
    26         android:layout_height="wrap_content"
    27         android:spinnerMode="dropdown" />
    28 
    29     <TextView
    30         android:layout_width="wrap_content"
    31         android:layout_height="wrap_content"
    32         android:text="entries绑定数据源" />
    33 
    34     <Spinner
    35         android:id="@+id/spinnerBase2"
    36         android:layout_width="match_parent"
    37         android:layout_height="wrap_content"
    38         android:entries="@array/beijing" />
    39 
    40     <TextView
    41         android:layout_width="wrap_content"
    42         android:layout_height="wrap_content"
    43         android:text="弹出带标题的Dialog,并且使用entries绑定数据源" />
    44 
    45     <Spinner
    46         android:id="@+id/spinnerBase3"
    47         android:layout_width="match_parent"
    48         android:layout_height="wrap_content"
    49         android:entries="@array/beijing"
    50         android:prompt="@string/beij_prompt"
    51         android:spinnerMode="dialog" />
    52 
    53 </LinearLayout>

    实现代码:

     1 package com.bgxt.datatimepickerdemo;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import android.app.Activity;
     7 import android.os.Bundle;
     8 import android.view.View;
     9 import android.widget.AdapterView;
    10 import android.widget.AdapterView.OnItemSelectedListener;
    11 import android.widget.ArrayAdapter;
    12 import android.widget.Spinner;
    13 import android.widget.Toast;
    14 
    15 public class SpinnerBaseActivity extends Activity {
    16     private Spinner spinner1, spinner2;
    17 
    18     @Override
    19     protected void onCreate(Bundle savedInstanceState) {
    20         super.onCreate(savedInstanceState);
    21         setContentView(R.layout.activity_spinnerbase);
    22 
    23         spinner1 = (Spinner) findViewById(R.id.spinnerBase);
    24         spinner2 = (Spinner) findViewById(R.id.spinnerBase1);
    25         // 声明一个ArrayAdapter用于存放简单数据
    26         ArrayAdapter<String> adapter = new ArrayAdapter<String>(
    27                 SpinnerBaseActivity.this, android.R.layout.simple_spinner_item,
    28                 getData());
    29         // 把定义好的Adapter设定到spinner中
    30         spinner1.setAdapter(adapter);
    31         spinner2.setAdapter(adapter);
    32         // 为第一个Spinner设定选中事件
    33         spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
    34 
    35             @Override
    36             public void onItemSelected(AdapterView<?> parent, View view,
    37                     int position, long id) {
    38                 // 在选中之后触发
    39                 Toast.makeText(SpinnerBaseActivity.this,
    40                         parent.getItemAtPosition(position).toString(),
    41                         Toast.LENGTH_SHORT).show();
    42             }
    43 
    44             @Override
    45             public void onNothingSelected(AdapterView<?> parent) {
    46                 // 这个一直没有触发,我也不知道什么时候被触发。
    47                 //在官方的文档上说明,为back的时候触发,但是无效,可能需要特定的场景
    48             }
    49         });
    50 
    51     }
    52 
    53     private List<String> getData() {
    54         // 数据源
    55         List<String> dataList = new ArrayList<String>();
    56         dataList.add("北京");
    57         dataList.add("上海");
    58         dataList.add("南京");
    59         dataList.add("宜昌");
    60         return dataList;
    61     }
    62 
    63 }

    XML资源文件:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <resources>
     3     <string name="app_name">SpinnerDemo</string>
     4     <string name="action_settings">Settings</string>
     5     <string name="hello_world">Hello world!</string>
     6     <string name="beij_prompt">北京区域</string> 
     7     <string-array name="beijing">
     8         <item>朝阳区</item>
     9         <item>海淀区</item>
    10         <item>房山区</item>
    11         <item>丰台区</item>
    12         <item>东城区</item>
    13         <item>西城区</item>
    14     </string-array>    
    15 </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是如何设置自定义格式数据的。

    布局代码:

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

    XML布局资源代码:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="wrap_content"
     5     android:orientation="horizontal" >
     6 
     7     <ImageView
     8         android:id="@+id/imageview"
     9         android:layout_width="60dp"
    10         android:layout_height="60dp"
    11         android:paddingLeft="10dp"
    12         android:src="@drawable/ic_launcher" />
    13 
    14     <TextView
    15         android:id="@+id/textview"
    16         android:layout_width="match_parent"
    17     android:layout_height="wrap_content"
    18         android:gravity="center_vertical" 
    19         android:paddingLeft="10dp"
    20         android:textColor="#000"
    21         android:textSize="16dp" />
    22 
    23 </LinearLayout>

    实现代码:

     1 package com.bgxt.datatimepickerdemo;
     2 
     3 import java.util.ArrayList;
     4 import java.util.HashMap;
     5 import java.util.List;
     6 import java.util.Map;
     7 
     8 import android.app.Activity;
     9 import android.os.Bundle;
    10 import android.view.View;
    11 import android.widget.AdapterView;
    12 
    13 import android.widget.AdapterView.OnItemSelectedListener;
    14 import android.widget.SimpleAdapter;
    15 import android.widget.Spinner;
    16 import android.widget.Toast;
    17 
    18 public class SpinnerAdapterActivity extends Activity {
    19     private Spinner spinner;
    20 
    21     @Override
    22     protected void onCreate(Bundle savedInstanceState) {
    23         // TODO Auto-generated method stub
    24         super.onCreate(savedInstanceState);
    25         setContentView(R.layout.activity_spinneradapter);
    26 
    27         spinner = (Spinner) findViewById(R.id.spinnerAdapter);
    28         //声明一个SimpleAdapter独享,设置数据与对应关系
    29         SimpleAdapter simpleAdapter = new SimpleAdapter(
    30                 SpinnerAdapterActivity.this, getData(), R.layout.items,
    31                 new String[] { "ivLogo", "applicationName" }, new int[] {
    32                         R.id.imageview, R.id.textview });
    33         //绑定Adapter到Spinner中
    34         spinner.setAdapter(simpleAdapter);
    35         //Spinner被选中事件绑定。
    36         spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    37 
    38             @Override
    39             public void onItemSelected(AdapterView<?> parent, View view,
    40                     int position, long id) {
    41                 //parent为一个Map结构的和数据
    42                 Map<String, Object> map = (Map<String, Object>) parent
    43                         .getItemAtPosition(position);
    44                 Toast.makeText(SpinnerAdapterActivity.this,
    45                         map.get("applicationName").toString(),
    46                         Toast.LENGTH_SHORT).show();
    47             }
    48 
    49             @Override
    50             public void onNothingSelected(AdapterView<?> arg0) {
    51                 
    52             }
    53         });
    54     }
    55 
    56     public List<Map<String, Object>> getData() {
    57         //生成数据源
    58         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    59         //每个Map结构为一条数据,key与Adapter中定义的String数组中定义的一一对应。
    60         Map<String, Object> map = new HashMap<String, Object>();
    61         map.put("ivLogo", R.drawable.bmp1);
    62         map.put("applicationName", "表情1");
    63         list.add(map);
    64         Map<String, Object> map2 = new HashMap<String, Object>();
    65         map2.put("ivLogo", R.drawable.bmp2);
    66         map2.put("applicationName", "表情2");
    67         list.add(map2);
    68         Map<String, Object> map3 = new HashMap<String, Object>();
    69         map3.put("ivLogo", R.drawable.bmp3);
    70         map3.put("applicationName", "表情3");
    71         list.add(map3);
    72         return list;
    73     }
    74 }

      效果展示:

     

    源码下载

    请支持原创,尊重原创,转载请注明出处。谢谢。

  • 相关阅读:
    C++学习9 this指针详解
    福建省第八届 Triangles
    UVA 11584 Partitioning by Palindromes
    POJ 2752 Seek the Name, Seek the Fame
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    HDU 2988 Dark roads(kruskal模板题)
    HDU 1385 Minimum Transport Cost
    HDU 2112 HDU Today
    HDU 1548 A strange lift(最短路&&bfs)
  • 原文地址:https://www.cnblogs.com/hudabing/p/4515115.html
Copyright © 2011-2022 走看看