最近用到Android中Spinner控件,搜了一下,网上文章要么语焉不详,要么只提到部分方法,着实不便。根据自己的使用经验,在此略作汇总(转载请注明出处)。(示例代码已经全部测试无误,可惜不能附加文件供下载)
修改Spinner的显示及下拉样式,先可以分为Spinner控件被加载前的静态设置和加载后的动态设置两类。
所谓加载前的静态设置也可以分成两种。一种(后文称A方法)就是最简单、最直接地在Layout的xml文件中设置属性值;另外一种(后文称B方法)就是先设计好Spinner将要使用的显示和下拉样式(XML文件),在生成Spinner将要加载的Adapter后,将XML文件指定给Adapter使用(如果不指定,Adapter将自动使用系统默认样式)。
所谓加载后的动态设置也可以分成两种。一种(后文称C方法)是自己编写Spinner将要加载的Adapter类,在自己的Adapter类方法中动态修改显示和下拉样式;另外一种(后文称D方法)就是直接在Spinner的事件中修改显示和下拉样式。
在分别掌握以上四种方法之后,如果能融会贯通,联合使用四种方法,可以设计出相当强大的效果哦。
下面对以上四种方法分别详细说明,文中引用部分代码说明。
A方法:
Layout XML 文件:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/myTextViewA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5sp"
android:text="A方法: " />
<Spinner
android:id="@+id/mySpinnerA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/myTextViewA"
android:background="@color/LIGHT_BLUE"
android:popupBackground="@color/LIGHT_GREEN" />
</RelativeLayout>
JAVA代码:
FixDataProvider 类:
package com.example.spinnerdemo;
import java.util.ArrayList;
import java.util.List;
public class FixDataProvider {
public static List<String> GetTenNumberList() {
// Create a List<String> for 0,1,2...9
List<String> list = new ArrayList<String>();
list.add("");
list.add("0");
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
return list;
}
}
MainActivity类:
package com.example.spinnerdemo;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
public class MainActivity extends Activity {
private Spinner mSpinnerA, mSpinnerB, mSpinnerC, mSpinnerD;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinnerA = (Spinner) this.findViewById(R.id.mySpinnerA);
this.loadDataForSpinnerA();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void loadDataForSpinnerA() {
List<String> spinnerList = FixDataProvider.GetTenNumberList();
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, spinnerList);
this.mSpinnerA.setAdapter(myAdapter);
}
}
注意:ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, spinnerList);是使用默认方式。
B方法:
Layout XML 文件:
1)将以下代码添加近activity_main.xml文件中以添加演示控件
<TextView
android:id="@+id/myTextViewB"
android:layout_below="@id/myTextViewA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5sp"
android:text="B方法: " />
<Spinner
android:id="@+id/mySpinnerB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/mySpinnerA"
android:layout_toRightOf="@id/myTextViewB" />
2)新建一个spinner_display_style.xml文件,在后面的JAVA代码中将设置作为Spinner控件的显示样式
<?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="vertical" >
<TextView
android:id="@+id/txtvwSpinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/LIGHT_BLUE"
android:textColor="@color/WHITE"
android:textStyle="bold|italic" />
</LinearLayout>
红色部分就是设置自己需要的显示样式,当然,读者可以加入更多的样式设置。
3)新建一个spinner_dropdown_style.xml文件,在后面的JAVA代码中将设置作为Spinner控件的下拉样式
<?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="vertical" >
<TextView
android:id="@+id/txtvwSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/LIGHT_GREEN"
android:textColor="@color/ORANGE"
android:textStyle="normal|italic" />
</LinearLayout>
红色部分就是设置自己需要的显示样式,当然,读者可以加入更多的样式设置。另外,如果改为android:layout_width="wrap_content",会有不同的下拉效果哦。
注意:spinner_display_style.xml和spinner_dropdown_style.xml中的TextView必须使用相同的名称,否则,系统会因为找不到TextView控件而抛出java.lang.NullPointerException错误!为什么会这样,本人还没有翻Spinner的源代码细究,有知道的大虾吱一声,谢谢!
JAVA代码:
MainActivity类:
1)在onCreate函数中加以下语句以获取需要的Spinner控件并执行加载数据函数
mSpinnerB = (Spinner) this.findViewById(R.id.mySpinnerB);
this.loadDataForSpinnerB();
2)生成loadDataForSpinnerB函数如下
private void loadDataForSpinnerB() {
List<String> spinnerList = FixDataProvider.GetTenNumberList();
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this,R.layout.spinner_display_style,R.id.txtvwSpinner, spinnerList);
myAdapter.setDropDownViewResource(R.layout.spinner_dropdown_style);
this.mSpinnerB.setAdapter(myAdapter);
}
红色代码部分就是分别设置Spinner控件的显示和下拉样式。设置显示样式时,除了指定要使用的xml文件,必须同时指定TextView。而设置下拉样式时,只要指定xml文家即可。
C方法:
示例说明:显示一个Spinner控件,下拉背景颜色为绿色,文字为红色,显示背景为蓝色,文字为白色。
将以下代码添加近activity_main.xml文件中以添加演示控件
<TextView
android:id="@+id/myTextViewC"
android:layout_below="@id/myTextViewB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5sp"
android:text="C方法: " />
<Spinner
android:id="@+id/mySpinnerC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/mySpinnerB"
android:layout_toRightOf="@id/myTextViewC" />
JAVA代码:
MainActivity类:
1)生成自定义ArrayAdapter类以供Spinner控件调用
package com.example.spinnerdemo;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MyArrayAdapter extends ArrayAdapter<String> {
private Context mContext;
private String[] mStringArray;
public MyArrayAdapter(Context context, String[] stringArray) {
// 注意:此处使用了系统默认item样式,所以getDropDownView和getView函数中TextView控件必须使用系统默认的text1名称
super(context,android.R.layout.simple_spinner_item, stringArray);
mContext = context;
mStringArray = stringArray;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// 修改Spinner下拉字体颜色
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
}
// 注意:text1是系统默认Spinner用来显示文字的TextView控件名称,不可以修改
TextView txtvwDropdown = (TextView) convertView.findViewById(android.R.id.text1);
txtvwDropdown.setText(mStringArray[position]);
txtvwDropdown.setTextSize(12f);
txtvwDropdown.setTextColor(Color.RED);
txtvwDropdown.setBackgroundColor(Color.GREEN);
return convertView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 修改Spinner显示字体颜色
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
}
//注意:text1是系统默认Spinner用来显示文字的TextView控件名称,不可以修改
TextView txtvwDisplay = (TextView) convertView.findViewById(android.R.id.text1);
txtvwDisplay.setText(mStringArray[position]);
txtvwDisplay.setTextSize(16f);
txtvwDisplay.setTextColor(Color.WHITE);
txtvwDisplay.setBackgroundColor(Color.BLUE);
return convertView;
}
}
2)在onCreate函数中加以下语句以获取需要的Spinner控件并执行加载数据函数
mSpinnerC = (Spinner) this.findViewById(R.id.mySpinnerC);
this.loadDataForSpinnerC();
private void loadDataForSpinnerC() {
// 使用自定义的ArrayAdapter生成Spinner数据源
ArrayAdapter<String> myAdapter = new MyArrayAdapter(this, new String[] { "", "1", "2", "3", "4", "5", "6", "7", "8", "9" });
this.mSpinnerC.setAdapter(myAdapter);
}
补充说明:上例中编写自定义ArrayAdapter类时使用了系统默认样式,如果要使用自定义样式,可以使用B方法中的做法,实现ArrayAdapter的另外一个构造函数
public MyArrayAdapter(Context context, List<String> objects) {
super(context, R.layout.spinner_display_style, R.id.txtvwSpinner, objects);
mContext = context;
mStringList = objects;
}
注意:使用如上构造函数后,getDropDownView和getView函数中TextView控件必须使用自定义Layout中的txtvwSpinner名称
另外,getDropDownView函数对应语句应做如下修改:
convertView = inflater.inflate(R.layout.spinner_dropdown_style, parent, false);
TextView txtvwDropdown = (TextView) convertView.findViewById(R.id.txtvwSpinner);
getView函数对应语句应做如下修改:
convertView = inflater.inflate(R.layout.spinner_display_style, parent, false);
TextView txtvwDisplay = (TextView) convertView.findViewById(R.id.txtvwSpinner);
D方法:
示例说明:显示一个Spinner控件,下拉背景颜色为绿色,文字为橙色;显示背景为蓝色,当是单数时文字为白色,当是双数时文字为红色。
单数:
双数:
Layout XML 文件:
将以下代码添加近activity_main.xml文件中以添加演示控件
<TextView
android:id="@+id/myTextViewD"
android:layout_below="@id/myTextViewC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5sp"
android:text="D方法: " />
<Spinner
android:id="@+id/mySpinnerD"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/mySpinnerC"
android:layout_toRightOf="@id/myTextViewD" />
JAVA代码:
MainActivity类:
1)在onCreate函数中加以下语句以获取需要的Spinner控件并执行加载数据函数,另外,指定Spinner的onItemSelectedListener监听器
mSpinnerD = (Spinner) this.findViewById(R.id.mySpinnerD);
this.loadDataForSpinnerD();
mSpinnerD.setOnItemSelectedListener(new MySpinnerItemSelectedListener());
private void loadDataForSpinnerD() {
List<String> spinnerList = FixDataProvider.GetTenNumberList();
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this, R.layout.spinner_display_style, R.id.txtvwSpinner, spinnerList);
myAdapter.setDropDownViewResource(R.layout.spinner_dropdown_style);
this.mSpinnerD.setAdapter(myAdapter);
}
private class MySpinnerItemSelectedListener implements OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
TextView txtvwSpinner = (TextView) view.findViewById(R.id.txtvwSpinner);
// 根据选择项来设置显示的字体颜色
if ((position - 1) % 2 == 0) {
txtvwSpinner.setTextColor(Color.RED);
} else {
txtvwSpinner.setTextColor(Color.WHITE);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
}
简单总结:以上四种方法是我自己知道的设置Spinner样式的途径,联合使用这四种方法,可以让我们更加灵活地使用Spinner控件。
延伸:以上示例中的Spinner控件仅仅显示了简单的文字,其实其功能远不止于此,但由于本文主题限于设置Spinner显示及下拉样式的四种方法介绍,所以不再枝蔓,如果有时间,我会再写一篇介绍用Spinner显示更为复杂一些的数据。