Spinner位于android.widget包下,它每次只显示用户选中的元素,当用户再次单击时,会弹出选择列表供用户选择,而选择列表中的元素同样来自适配器(Adapter),如图所示为该类的继承树,我们可以看出,Spinner类仍然为View的一个子类。
下面将通过一个选择爱好的案例来介绍Spinner类控件的使用方法,需要注意的是,Android中的下拉列表并不像其他系统那样直接下拉来显示选项,而是相当于一个弹出菜单供用户选择的。
(1)新建Android项目,项目名称为Samples_5_1.
(2)将兴趣爱好的图片资源存放到res/drawable-mdpi文件夹下。如下图所示:
(3)添加字符串资源,修改res/values目录下得strings.xml文件,添加如下选项。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Samples_5_1</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<!--定义ys字符串-->
<string name="ys">您的爱好</string>
<!--定义lq字符串-->
<string name="lq">篮 球</string>
<!--定义zq字符串-->
<string name="zq">足 球</string>
<!--定义pq字符串-->
<string name="pq">排 球</string>
</resources>
(4)添加颜色资源,在res/values目录下创建color.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义red颜色-->
<color name="red">#FF4040</color>
<!--定义green颜色-->
<color name="green">#98FB98</color>
<!--定义blue颜色-->
<color name="blue">#00B2EE</color>
<!--定义white颜色-->
<color name="white">#FCFCFC</color>
<!--定义black颜色-->
<color name="black">#1A1A1A</color>
</resources>
(5)修改布局文件,修改activity_main.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical"
>
<!--添加一个TextView控件-->
<TextView
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="28dip"/>
<!--添加一个下拉列表控件-->
<Spinner
android:id="@+id/Spinner01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
(6)下面是主要逻辑代码,打开Samples_5_1.java
package com.example.samples_5_1;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Spinner;
import android.widget.BaseAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ImageView;
import android.widget.AdapterView;
public class MainActivity extends Activity {
final static int WRAP_CONTENT=-2; //WRAP_CONTENT常量
//所有资源图片(足球。篮球、排球)id的数据
int [ ] drawableIds=new int[]{R.drawable.f,R.drawable.b,R.drawable.v};
//所有资源字符串(足球、篮球、排球)id的数组
int [ ] msgIds=new int[]{R.string.zq,R.string.lq,R.string.pq};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化Spinner
Spinner sp=(Spinner)this.findViewById(R.id.Spinner01);
BaseAdapter ba=new BaseAdapter()
{
@Override
//为Spinner准备内容适配器
public int getCount()
{
return 3;
}
//重写getItem方法
@Override
public Object getItem(int arg0)
{
return null;
}
@Override
public long getItemId(int arg0)
{
return 0;
}
@Override
public View getView(int arg0,View arg1,ViewGroup arg2)
{
/**
* 动态生成每个下拉项对应的View,每个下拉项View由LinearLayout
* 中包含一个ImageView及一个TextView构成
*/
//初始化LinearLayout
LinearLayout ll=new LinearLayout(MainActivity.this);
//设置朝向
ll.setOrientation(LinearLayout.HORIZONTAL);
//初始化ImageView
ImageView ii=new ImageView(MainActivity.this);
//设置内容
ii.setImageDrawable(MainActivity.this.getResources().getDrawable(drawableIds[arg0]));
//添加到LinearLayout中
ll.addView(ii);
//初始化TextView
TextView tv=new TextView(MainActivity.this);
//设置内容
tv.setText(MainActivity.this.getResources().getText(msgIds[arg0]));
//设置字体大小
tv.setTextSize(24);
//设置字体颜色
tv.setTextColor(MainActivity.this.getResources().getColor(R.color.black));
//将LinearLayout返回
ll.addView(tv);
return ll;
}
};
//为Spinner设置内容适配器
sp.setAdapter(ba);
//设置选项选中的监听器
sp.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0,View arg1,int arg2,long arg3)
{
//获取主界面TextView
TextView tv=(TextView)MainActivity.this.findViewById(R.id.TextView01);
//获取当前选中的LinearLayout
LinearLayout ll=(LinearLayout)arg1;
//获取其中的TextView
TextView tvn=(TextView)ll.getChildAt(1);
//用StringBuilder动态生成信息
StringBuilder sb=new StringBuilder();
sb.append(MainActivity.this.getResources().getText(R.string.ys));
sb.append(":");
sb.append(tvn.getText());
tv.setText(sb.toString());
}
//重写onNothingSelected方法
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
}
(7)运行效果如下图所示:
(8)对主要逻辑代码进行简单解释一下。
a.代码中使用了BaseAdapter适配器提供数据,关于BaseAdapter适配器的详细介绍在我的博客中有详细介绍,这里简单介绍一下。下图为BaseAdapter类的构造:
从编译的类可以看出BaseAdapter实现了android.widget.ListAdapter和android.widget.SpinnerAdapter接口。既然实现了这两个需要实现接口中的方法。下面再来看android.widget.ListAdapter接口和android.widget.SpinnerAdapter接口。
android.widget.ListAdapter接口
android.widget.SpinnerAdapter接口
从这两个接口的编译类中可以看出他们都继承自android.widget.Adapter类,那么该类又有哪些方法需要实现呢,看了下图就知道了。
因为BaseAdapter已经是抽象类了,在该类中已经实现了接口中所有方法,只需要重写实现Spinner数据红色标注的四个方法,这些方法都是继承过来。下面主要介绍一下getView方法,因为getView是数据适配器具体实现的方法。
getView类的定义
getView类的参数及返回值
b.代码中还使用到了setOnItemSelectedListener方法用于对Spinner选项的监听。
下面来看下实现监听功能的类OnItemSelectedListener类。
setOnItemSelectedListener方法是Spinner类继承过来的方法。
1.Spinner继承自 android.widget.AbsSpinner类
2.AbsSpinner继承自 android.widget.AdapterView<android.widget.SpinnerAdapter>类
3.可以看出setOnItemSelectedListener是 android.widget.AdapterView<T extends android.widget.Adapter>抽象类的方法。红色标示的即setOnItemSelectedListener方法。而监听的类是android.widget.AdapterView$OnItemSelectedListener类。下面来看下这个类的接口方法以便Spinner类实现该接口中的方法。
4.从下图可以看出,Spinner类需要重写 onItemSelected和onNothingSelected这两个方法
至此所有的功能介绍也已经完成,学习Java时一定要从面向对象的角度去考察功能的实现,这样就很清楚哪些功能需要实现哪些方法。