Spinner相当于下拉列表,在Android开发文档中的关于Spinner的介绍:
android.widget
类 Spinner
java.lang.Object android.view.View android.view.ViewGroup android.widget.AdapterView<SpinnerAdapter> android.widget.AbsSpinner android.widget.Spinner
-
所有已实现的接口:
- DialogInterface.OnClickListener, Drawable.Callback, KeyEvent.Callback, ViewManager, ViewParent
A view that displays one child at a time and lets the user pick among them.
The items in the Spinner come from the Adapter
associated with this view.
Spinner是一个view,一个每次只能展现一个子元素并且可以让用户从它子元素中选择一个。它的子元素来自之于和这个view绑定的适配器。
从官方文档中我们可以看出,要想使用spinner必须要一个Adapter,它是这个Spinner的数据源。
那我们先建立一个数据源:数据源有两种形式,1.直接新建一个数组2.在strings.xml中声明。
我们先在strings.xml中声明一个数组:
<string-array name="cities">
<item>北京</item>
<item>上海</item>
</string-array>
里面只有两个数据,北京和上海。下面是实现代码:
String []cities = String []items = getResources().getStringArray(R.array.cities);
Adapter <String>myAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,cities);
aadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp_spinner01.setAdapter(aadapter);
这样就把这个适配器绑定到了这个spinner上了。下面是监听:
sp_spinner01.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
Log.i("abc", "arg1="+arg2+"text="+arg0.getItemAtPosition(arg2).toString());
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
Log.i("abc","你什么都没选择");
}
});
获取选择的内容要用:arg0.getItemAtPosition(arg2),第二参数是选择的内容所在数组的下标。这样一个基础的Spinner就可以运行了,运行结果如下:
按照惯例,我们一般不会使用系统提供的Spinner,一般都是使用自定义的Spinner,从上面的例子我们可以看出来如果要使用自定义的Spinner,需要有一个Adapter,还有一个layout用于承载每一个Item。Android系统提供的样式不太好看,我希望每一个Item都有一个图片还有相应的文字,这样的话我们可以自己来定义一下:
在layout目录下新建一个Items.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="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_icon"
android:layout_width="0dp"
android:layout_weight="5"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/tv_content"
android:layout_width="0dp"
android:layout_weight="5"
android:layout_height="match_parent"
android:gravity="center"/>
</LinearLayout>
这里包含一个ImageView和一个TextView。
最重要的就是我们的Adapter,要从BaseAdapter继承。
package com.example.widgetstest;
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.ImageView;
import android.widget.TextView;
public class MyOwnAdapter extends BaseAdapter {
private List<Items>myList;
private Context myContext;
public MyOwnAdapter(List<Items>myList,Context context) {
// TODO Auto-generated constructor stub
this.myList = myList;
this.myContext = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return myList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return myList.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
LayoutInflater _myInflater = LayoutInflater.from(myContext);
arg1 = _myInflater.inflate(R.layout.spinner_item, null);
if(arg1 != null){
TextView content = (TextView)arg1.findViewById(R.id.tv_content);
content.setText(myList.get(arg0).getItem());
int imageIcon = R.drawable.ic_launcher;
switch(arg0){
case 0: imageIcon = R.drawable.broadcasting_system_monitor;
break;
case 1: imageIcon = R.drawable.parking_monitor;
break;
case 2 : imageIcon = R.drawable.device_alarming;
break;
}
ImageView icon = (ImageView)arg1.findViewById(R.id.iv_icon);
icon.setImageResource(imageIcon);
}
return arg1;
}
}
getView方法是这里最重要的一个方法,重点看一下思路是:通过LayoutInflater的from(Context)方法获取当前上下文的视图容器,然后再或许我们自定义的Item样式的xml文件,获取后就是可以对其做一些操作。最后将这个设置好的view返回。
新建一个Items类内容为:
package com.example.widgetstest;
public class Items {
Items(){}
Items(String items){
this.item = items;
}
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}
这里只是一个简单的演示,如果想要更复杂里的话,可以自己修改。
然后就是在Activity中的调用:
Spinner mySpinner = (Spinner)findViewById(R.id.my_spinner);
List <Items>_items = new ArrayList<Items>();
_items.add(new Items("报警"));
_items.add(new Items("停车"));
_items.add(new Items("广播"));
MyOwnAdapter _myAdapter = new MyOwnAdapter(_items,this);
mySpinner.setAdapter(_myAdapter);
mySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
Items t = (Items) arg0.getItemAtPosition(arg2);
Log.i("abc",t.getItem().toString());
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
这里有一点一定要注意,就是getItemAtPosition()的返回值的问题,刚开始的时候我返回的内容使用toString()方法后显示的是一团序列化的数字而并非我想要的内容查了一下API才发现:
public Object getItemAtPosition(int position) {
T adapter = getAdapter();
return (adapter == null || position < 0) ? null : adapter.getItem(position);
}
这个方法其实又调用了我们的adapter里的getItem方法,再看一下我写的这个方法的定义:
public Object getItem(int arg0) {
return myList.get(arg0);
}
这里返回的是myList里的数据,而我的myList中装入的数据是:
List <Items>_items = new ArrayList<Items>();
因此这里返回必然是一个Items对象,因此需要:
Items t = (Items) arg0.getItemAtPosition(arg2);
然后调用这个Item对象的get方法才能获取到这个值。
运行结果如下: