PS:看了9年的小说,自己开始动手写了一本

还记得以前有过想自定义spinner样式,但上网一搜都是让你使用popupwindow去代替spinner,此时有时根本不用那么麻烦。接下来便跟大家一起来看看如何自定义spinner。

首先先看下效果图

android item样式效果 android spinner样式_xml


接下来贴上几个布局

1. activity_main.xml

<span >	</span><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    	<span >	</span>xmlns:tools="http://schemas.android.com/tools"
   	 	android:layout_width="match_parent"
    	<span >	</span>android:layout_height="match_parent" >

    	<span >	</span><Spinner
        	<span >	</span>android:id="@+id/sp"
        	<span >	</span>android:layout_width="wrap_content"
        	<span >	</span>android:layout_height="wrap_content"
       	<span >		</span>android:layout_centerInParent="true" />

<span >	</span></RelativeLayout>

很简单,就一个Spinner控件

2. simple_spinner_item.xml(选中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="wrap_content"
    android:background="@android:color/white"
    android:orientation="horizontal" >
    
    <ImageView 
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/ic_launcher"/>

    <TextView
        android:id="@id/tv_spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/spinnerItemStyle"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:gravity="right"
        android:textSize="14sp"/>

</LinearLayout>

3.simple_spinner_dropdown_item.xml(下来的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" >
    
    <ImageView 
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/ic_launcher"/>

    <TextView
        android:id="@id/tv_spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="8dp"
        android:textSize="14sp"
        android:singleLine="true" />

</LinearLayout>

这里展示的布局和下拉item显示的布局基本一样,当然你可以自定义成你想要展示的布局。

开始上代码

public class MainActivity extends Activity {
	private Spinner spinner;
	private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        spinner = (Spinner) findViewById(R.id.sp);
        
        adapter = new ArrayAdapter<String>(this,
				R.layout.simple_spinner_item, R.id.tv_spinner);

        adapter
				.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
        adapter.add("text1");
        adapter.add("text2");
        adapter.add("text3");
        adapter.add("text3");

		spinner.setAdapter(adapter);
    }

}

就是如此简单,最关键的就是要保持simple_spinner_item.xml和simple_spinner_dropdown_item.xml两个布局中用于展示文字所用的id是一致的。

那如何保证两个textview的id一致呢?

只需在values目录下新建个ids.xml文件,在里面先声明变可以了

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="tv_spinner" type="id"></item>
</resources>

至于我是如何知道的,我想不用说大家都猜得到,看源码呗,源码面前了无秘密。只需要跟进ArrayAdapter里面查看源码,便可知道若是我们没指定textview的id,它会使用默认的id去获取textview,也就是ArrayAdapter默认布局里textview的id。若是指定了id,在ArrayAdapter里面会用同一个id去获取两个布局中的textview,因此默认显示和下拉的item里用于展示文字的textview必须是相同的id,否则肯定报错。

当然啦,这种自定义对于一些简单的要求还是很方便的,当若是传入的数据是一些比较复杂的对象类型,且要展示的不止一个数据,那就不适合了。

你或许会有疑问,竟然这样那我直接都使用popupwind自定义不就好了,干嘛还要这么折腾。其实主要是使用spinner你不用再自己去控制弹出的选择框要在展示的文本下方还是上方,系统已经帮你处理了,可以省去很多麻烦。