Android学习——Spinner实现下拉列表

一、Spinner简介

  在Web开发中,HTML提供了下拉列表的实现,就是使用<select>元素实现一个下拉列表,在其中每个下拉列表项使用<option>表示即可。这是在Web开发中一个必不可少的交互性组件,而在Android中的对应实现就是Spinner。

  在编码的同时,首先需要在布局中设定Spinner组件,然后将可选内容通过ArrayAdapter和下拉列表连接起来,最后要获得用户选择的选项,我们需要设计事件监听器setOnItemSelectedListener并实现onItemSelected,从而获得用户所选择的内容,最后通过setVisibility方法设置当前的显示项

二、使用方法

1、以资源方式,静态展示 Spinner 选项:

 布局文件:

<Spinner 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/spinner2"
    android:entries="@array/spingarr"
    />
main.xml

  数据文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="spingarr">
     <item>北京</item>  
    <item>上海</item>  
    <item>广州</item>  
    <item>深圳</item>  
    </string-array>
</resources>
下拉列表框选项

  效果图:

  【注意】在<Spinner>标签中,通过android:prompt来设置弹出选择框的标题,通过android:entries来设置默认的列表选项,可以直接在xml布局文件中绑定数据源(也可以不在xml布局文件中设置,而在Activity中动态绑定)

 

2、以代码方式,动态展示 Spinner 选项(用适配器给Spinner添加数据)

  布局文件:

<Spinner 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/spinner"
    />
main.xml

  自定数据源:

package com.example.testspanner;

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

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;


public class MainActivity extends Activity {
private Spinner spinner;
private List<String> data_list;
private ArrayAdapter<String> arr_adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.spinner);
        spinner = (Spinner) findViewById(R.id.spinner);
    
        //数据
        data_list = new ArrayList<String>();
        data_list.add("北京");
        data_list.add("上海");
        data_list.add("广州");
        data_list.add("深圳");
        
        //适配器
        arr_adapter= new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, data_list);
        //设置样式
        arr_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        //加载适配器
        spinner.setAdapter(arr_adapter);
        
    }

}
MainActivity.java

 

3、使用ArrayAdapter进行适配数据:

   ①:首先定义一个布局文件:

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

         ②:建立数据源,使用数组,这些数据将会在Spinner下来列表中进行显示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="spinnername">
        <item>北京</item>
        <item>上海 </item>
        <item>广州</item>
        <item>深圳</item>
    </string-array>
</resources>
下拉列表框选项

  ③:接着在Activity中加入如下的代码(使用了系统定义的下拉列表的布局文件,当然也可以自定义)

// 初始化控件
mSpinner = (Spinner) findViewById(R.id.spinner1);
// 建立数据源
String[] mItems = getResources().getStringArray(R.array.spinnername);
// 建立Adapter并且绑定数据源
ArrayAdapter<String> _Adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, mItems);
//绑定 Adapter到控件
mSpinner.setAdapter(_Adapter);
View Code

  下面是关于Spinner的点击事件(效果图如下图):

mSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view,
            int position, long id) {
        String str=parent.getItemAtPosition(position).toString();
        Toast.makeText(SpinnerActivity.this, "你点击的是:"+str, 2000).show();
    }
    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        // TODO Auto-generated method stub
    }
});
吐司显示选择项

 

4、使用自定义的Adapter(重点)

   ①:定义每一个Item的布局文件

<?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="horizontal" >
 
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/ic_launcher"
        android:paddingRight="8dip"
        android:paddingTop="8dip"
        android:text="TextView"
        android:textSize="25sp" />
 
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="8dip"
        android:paddingTop="8dip"
        android:text="TextView"
        android:textSize="25sp" />
 
</LinearLayout>
Item.xml

  ②:建立Person类:

package com.jiangqq.csdn;
public class Person {
    private String personName;
    private String personAddress;
    public Person(String personName, String personAddress) {
        super();
        this.personName = personName;
        this.personAddress = personAddress;
    }
    public String getPersonName() {
        return personName;
    }
    public void setPersonName(String personName) {
        this.personName = personName;
    }
    public String getPersonAddress() {
        return personAddress;
    }
    public void setPersonAddress(String personAddress) {
        this.personAddress = personAddress;
    }
 
}
Person.java

     ③:创建MyAdapter继承与BaseAdapter,进行适配:

package com.jiangqq.csdn;
 
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
 
/**
 * 自定义适配器类
 * @author jiangqq  <a href=http://blog.csdn.net/jiangqq781931404></a>
 *
 */
public class MyAdapter extends BaseAdapter {
    private List<Person> mList;
    private Context mContext;
 
    public MyAdapter(Context pContext, List<Person> pList) {
        this.mContext = pContext;
        this.mList = pList;
    }
 
    @Override
    public int getCount() {
        return mList.size();
    }
 
    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }
 
    @Override
    public long getItemId(int position) {
        return position;
    }
    /**
     * 下面是重要代码
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater _LayoutInflater=LayoutInflater.from(mContext);
        convertView=_LayoutInflater.inflate(R.layout.item, null);
        if(convertView!=null)
        {
            TextView _TextView1=(TextView)convertView.findViewById(R.id.textView1);
            TextView _TextView2=(TextView)convertView.findViewById(R.id.textView2);
            _TextView1.setText(mList.get(position).getPersonName());
            _TextView2.setText(mList.get(position).getPersonAddress());
        }
        return convertView;
    }
}
 
MyAdapter.java

  ④:在Activity中加入如下代码: 

 // 初始化控件
mSpinner = (Spinner) findViewById(R.id.spinner1);
// 建立数据源
List<Person>  persons=new ArrayList<Person>();
persons.add(new Person("张三", "上海 "));
persons.add(new Person("李四", "上海 "));
persons.add(new Person("王五", "北京" ));
persons.add(new Person("赵六", "广州 "));
//  建立Adapter绑定数据源
MyAdapter _MyAdapter=new MyAdapter(this, persons);
//绑定Adapter
mSpinner.setAdapter(_MyAdapter);
MainActivity.java

运行效果如下截图:

  

  监听事件和第一种方法相同

 

5、示例代码:

使用数组作为数据源

  (1).新建一个android的工程
  (2).工程的layout.xml文件如下:声明一个TextView控件和一个Spinner控件 

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

  (3)、java代码

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
 
public class SpinnerActivity extends Activity {
     
    private static final String[] m={"A型","B型","O型","AB型","其他"};
    private TextView view ;
    private Spinner spinner;
    private ArrayAdapter<String> adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.spinner);
         
        view = (TextView) findViewById(R.id.spinnerText);
        spinner = (Spinner) findViewById(R.id.Spinner01);
        //将可选内容与ArrayAdapter连接起来
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,m);
         
        //设置下拉列表的风格
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         
        //将adapter 添加到spinner中
        spinner.setAdapter(adapter);
         
        //添加事件Spinner事件监听  
        spinner.setOnItemSelectedListener(new SpinnerSelectedListener());
         
        //设置默认值
        spinner.setVisibility(View.VISIBLE);
         
    }
     
    //使用数组形式操作
    class SpinnerSelectedListener implements OnItemSelectedListener{
 
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            view.setText("你的血型是:"+m[arg2]);
        }
 
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    }
}
SpinnerActivity.java

  (4)、运行效果如下:



   

 

 

使用XML作为数据源

  (1).新建一个android的工程
  (2).在values文件夹下新建一个arryas.xml文件:声明一个TextView控件和一个Spinner控件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="plantes">
        <item>NOKIA</item>
        <item>MOTO</item>
        <item>HTC</item>
        <item>LG</item>
        <item>其他</item>
    </string-array>
</resources>
arryas.xml

  (3).java代码

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
 
public class SpinnerActivity extends Activity {
     
    private TextView view2;
    private Spinner spinner2;
    private ArrayAdapter adapter2;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.spinner);
 
        spinner2 = (Spinner) findViewById(R.id.spinner02);
        view2 = (TextView) findViewById(R.id.spinnerText02);
 
        //将可选内容与ArrayAdapter连接起来
        adapter2 = ArrayAdapter.createFromResource(this, R.array.plantes, android.R.layout.simple_spinner_item);
 
        //设置下拉列表的风格 
 adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 
        //将adapter2 添加到spinner中
        spinner2.setAdapter(adapter2);
 
        //添加事件Spinner事件监听  
        spinner2.setOnItemSelectedListener(new SpinnerXMLSelectedListener());
 
        //设置默认值
        spinner2.setVisibility(View.VISIBLE);
         
    }
     
    //使用XML形式操作
    class SpinnerXMLSelectedListener implements OnItemSelectedListener{
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            view2.setText("你使用什么样的手机:"+adapter2.getItem(arg2));
        }
 
        public void onNothingSelected(AdapterView<?> arg0) {
             
        }
         
    }
}
SpinnerActivity.java

  (4)、运行效果如下:
 

 

示例代码:

public class MainActivity extends Activity {
    private Spinner spinner;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        spinner = (Spinner) findViewById(R.id.spinner);
        textView = (TextView) findViewById(R.id.textViewId);
        // 创建一个ArrayAdapter
        // 静态使用xml文件设置下拉列表内容
        /**
         * ArrayAdapter参数说明: 
   * 第一个:上下文对象 
         * 第二个:下拉菜单数据来源的id
         * 第三个:下拉菜单的样式,这里使用了android标准下拉菜单的样式
         */
        // ArrayAdapter<CharSequence> adapter =
        // ArrayAdapter.createFromResource(this, R.array.ThreeDays,
        // android.R.layout.simple_spinner_item);
        // 调用setDropDownViewResource()方法设置下拉列表每一个选项的样式,这里也是用Android标准样式
        // adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // 动态设置下拉列表内容
        List<String> list = new ArrayList<String>();
        list.add("昨天");
        list.add("今天");
        list.add("明天");
        /**
         * 参数 
         *第一个:上下文对象 
         *第二个:自定义下拉菜单的选项的样式
         * 第三个:自定义下拉菜单选项控件的样式id
         * 第四个:列表数据
         */
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.list, R.id.list_textViewId, list);
        // 为spinner添加适配器
        spinner.setAdapter(adapter);
        // 设置Spinner下拉列表的标题··
        spinner.setPrompt("只有这三天");
        // 为spinner绑定监听器
        spinner.setOnItemSelectedListener(new SpinnerListener());
    }

    // 该监听器用于监听用户多spinner的操作
    class SpinnerListener implements OnItemSelectedListener {
        // 当用户选择先拉列表中的选项时会调用这个方法
        /**
         * 参数说明:
         * 第一个:当前的下拉列表,也就是第三个参数的父view 
         *第二个:当前选中的选项
         *第三个:所选选项的位置
         *第四个: 所选选项的id
         */
        public void onItemSelected(AdapterView<?> adapterView, View view,
                int position, long id) {
            // 获取用户所选的选项内容
            String selected = "您的选择是:"
                    + adapterView.getItemAtPosition(position).toString();
            textView.setText(selected);
            Toast.makeText(MainActivity.this, selected, Toast.LENGTH_SHORT)
                    .show();
        }

        // 当用户不做选择时调用的该方法
        public void onNothingSelected(AdapterView<?> arg0) {
            Toast.makeText(MainActivity.this, "您没有选择任何选项", Toast.LENGTH_SHORT)
                    .show();
        }
    }

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

示例代码:

package cn.com;

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

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

public class SpinnerActivity extends Activity {
    /** Called when the activity is first created. */  
    private List<String> list = new ArrayList<String>();  
    private TextView myTextView;  
    private Spinner mySpinner;  
    private ArrayAdapter<String> adapter;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        //第一步:添加一个下拉列表项的list,这里添加的项就是下拉列表的菜单项  
        list.add("北京");  
        list.add("上海");  
        list.add("深圳");  
        list.add("福州");  
        list.add("厦门");  
        myTextView = (TextView)findViewById(R.id.TextView_city);  
        mySpinner = (Spinner)findViewById(R.id.Spinner_city);  
        //第二步:为下拉列表定义一个适配器,这里就用到里前面定义的list。  
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list);  
        //第三步:为适配器设置下拉列表下拉时的菜单样式。  
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);  
        //第四步:将适配器添加到下拉列表上  
        mySpinner.setAdapter(adapter);  
        //第五步:为下拉列表设置各种事件的响应,这个事响应菜单被选中  
        mySpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){  
            public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
                // TODO Auto-generated method stub  
                /* 将所选mySpinner 的值带入myTextView 中*/  
                myTextView.setText("您选择的是:"+ adapter.getItem(arg2));  
                /* 将mySpinner 显示*/  
                arg0.setVisibility(View.VISIBLE);  
            }  
            public void onNothingSelected(AdapterView<?> arg0) {  
                // TODO Auto-generated method stub  
                myTextView.setText("NONE");  
                arg0.setVisibility(View.VISIBLE);  
            }  
        });  
        /*下拉菜单弹出的内容选项触屏事件处理*/  
        mySpinner.setOnTouchListener(new Spinner.OnTouchListener(){  
            public boolean onTouch(View v, MotionEvent event) {  
                // TODO Auto-generated method stub  
                /**
                 * 
                 */
                return false;  
            }
        });  
        /*下拉菜单弹出的内容选项焦点改变事件处理*/  
        mySpinner.setOnFocusChangeListener(new Spinner.OnFocusChangeListener(){  
        public void onFocusChange(View v, boolean hasFocus) {  
            // TODO Auto-generated method stub  

        }  
        });  
    }  
}
核心参考代码

 

三、根据城市的选择,自动显示后边的城区选择

 

  .xml文件

<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="horizontal"
    tools:context=".MainActivity" >


   
    <Spinner 
        android:id="@+id/ciyt"
        android:prompt="@string/city_prompt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"       
        android:entries="@array/cities"/>
    
    <Spinner 
        android:id="@+id/area"
        android:prompt="@string/city_prompt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    
</LinearLayout>
main.xml
  
  .java文件
 
public class MainActivity extends Activity {
    // 城市
    private Spinner city = null;
    // 城市下边的子成区
    private Spinner area = null;
    private String[][] areaData = new String[][] { { "东城", "西城", "海淀", "上地" },
            { "陆家嘴", "黄埔", "金融街" }, { "宝安区", "深圳区", "中山区" } };
    private ArrayAdapter<CharSequence> adapterArea = null;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.city = (Spinner) super.findViewById(R.id.ciyt);
        this.area = (Spinner) super.findViewById(R.id.area);
        this.city.setOnItemSelectedListener(new OnItemSelectedListenerImp());
    }

    private class OnItemSelectedListenerImp implements OnItemSelectedListener {

        public void onItemSelected(AdapterView<?> parent, View view,
                int position, long id) {
            // 得到选择的选项
            MainActivity.this.adapterArea = new ArrayAdapter<CharSequence>(
                    MainActivity.this, android.R.layout.simple_spinner_item,
                    MainActivity.this.areaData[position]);
            MainActivity.this.adapterArea
                    .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            MainActivity.this.area.setAdapter(MainActivity.this.adapterArea);
        }

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

}
MainActivity.java

 

  values当中的city.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="cities">
        <item>北京</item>
        <item>上海</item>
        <item>深圳</item>
    </string-array>
</resources>
city.xml

 

四、android spinner下拉样式介绍

1、更换android.R xml样式

以下为引用内容: 
ArrayAdapter< String> adapter = new ArrayAdapter< String>( this, android.R.layout.simple_spinner_item);

这里面的第二个参数是android.R系统自带的xml样式,我们更换这个时就会看到生成的spinner的直观样式如下:

android spinner 样式
图1

如果换成android.R.layoutbrowser_link_context_header那么样式变为:

android spinner 样式
图2

同理:android.R.pinner_dropdown:

android spinner 样式

android.R.preference_category:

android spinner 样式
图4

android.R.simple_spinner_item

android spinner 样式
图5

android.R.select_dialog_item:

android spinner 样式
图6

android.R.select_dialog_multichoice

android spinner 样式
图7

android.R.select_dialog_singlechoice

android spinner 样式
图8

android.R.simple_dropdown_item_1line

android spinner 样式
图9

android.R.simple_expandable_list_item_1

android spinner 样式
图10

android.R.simple_gallery_item

android spinner 样式
图11

android.R.simple_list_item_1

android spinner 样式
图12

android.R.simple_list_item_checked

android spinner 样式
图13

android.R.simple_list_item_multiple_choice

android spinner 样式
图14

android.R.simple_list_item_single_choice

android spinner 样式
图15

android.R.simple_spinner_dropdown_item

android spinner 样式
图16

android.R.simple_spinner_item

android spinner 样式
图17

android.R.test_list_item

android spinner 样式
图18

还有自定义的spinner.xml :

以下为引用内容: 
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text1" 
android:layout_width="60px" 
android:layout_height="wrap_content"
android:singleLine="true"
style="?android:attr/spinnerItemStyle"
/>

android spinner 样式
图19

2、下拉列表弹出样式

更换 xml 参数

以下为引用内容: 
adapter.setDropDownViewResource(android.R.layout.test_list_item);

android.R.browser_link_context_header :

android spinner 样式
图20

preference_category :

android spinner 样式
图21

select_dialog_item:

android spinner 样式
图22

select_dialog_multichoice:多选样式,可惜不能多选。

android spinner 样式
图23

select_dialog_singlechoice:

android spinner 样式
图24

simple_dropdown_item_1line:

android spinner 样式
图25

simple_list_item_checked:

android spinner 样式
图26

simple_list_item_single_choice:

android spinner 样式
图27

posted @ 2015-03-20 01:24  数据探索者  阅读(25535)  评论(0编辑  收藏  举报