一、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
示例代码:
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的直观样式如下:
图1
如果换成android.R.layoutbrowser_link_context_header那么样式变为:
图2
同理:android.R.pinner_dropdown:
android.R.preference_category:
图4
android.R.simple_spinner_item
图5
android.R.select_dialog_item:
图6
android.R.select_dialog_multichoice
图7
android.R.select_dialog_singlechoice
图8
android.R.simple_dropdown_item_1line
图9
android.R.simple_expandable_list_item_1
图10
android.R.simple_gallery_item
图11
android.R.simple_list_item_1
图12
android.R.simple_list_item_checked
图13
android.R.simple_list_item_multiple_choice
图14
android.R.simple_list_item_single_choice
图15
android.R.simple_spinner_dropdown_item
图16
android.R.simple_spinner_item
图17
android.R.test_list_item
图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"
/>
图19
2、下拉列表弹出样式
更换 xml 参数
以下为引用内容:
adapter.setDropDownViewResource(android.R.layout.test_list_item);
android.R.browser_link_context_header :
图20
preference_category :
图21
select_dialog_item:
图22
select_dialog_multichoice:多选样式,可惜不能多选。
图23
select_dialog_singlechoice:
图24
simple_dropdown_item_1line:
图25
simple_list_item_checked:
图26
simple_list_item_single_choice:
图27