- 要实现的目标:如下图,乡镇根据区改变,村根据乡镇改变.选中为红色,默认黑色
大致步骤
一. 首先需要三个spinner控件
- 属性:
- spinnerMode 表示下拉列表样式,一种弹窗式,一种下拉式.
- 有textColor属性,但是不起作用,颜色的设置要在适配器写,下面再说
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="15dp"
android:paddingBottom="10dp">
<Spinner
android:id="@+id/area"
android:theme="@style/TabLayoutTabStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown"></Spinner>
<Spinner
android:id="@+id/town"
style="?android:spinnerItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown"></Spinner>
<Spinner
android:id="@+id/village"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown"></Spinner>
</LinearLayout>
二. 为spinner添加文本
做完第一步显示效果仅仅是三个箭头而已,内容是空,需要为它设置包含内容的TextView.写在spinner_item.xml内
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_view"
android:text="test"
android:textSize="13sp"
android:textColor="@color/spinnerText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
三. 为spinner添加适配器
- 适配器的作用:
- 为spinner设计样式,如文字颜色,大小等.这里为选中和未选中设置不同颜色
- 为spinner设置内容,绑定数据.这里绑定区/镇/村的内容,并设计关联方法
关于联动的实现分析:
- 思路: 原始列表中,所有地区的乡镇和村都是混在一起的. 当选中区之后,乡镇只有本区的那几个才显示,这就要求不同区的选中会提供不同的参数来决定乡镇,同理乡镇也会提供参数决定村.反过来,每个村也只对应着一个乡镇,每个乡镇对应一个区. 也就是说他们的关系类似祖孙三辈
- 所以可以这样设计数据结构:把地区都封装成一个对象,这个对象有两个属性,一个是自己的id,一个是父级的id,这样当区固定后,只需显示父级id为该区id的乡镇即可,完美解决
- 具体实现就是预先把所有的地区列表传入,然后当上一级选中后,把选中对象的id作为参数传入Adapter中,来筛选这一级有哪些符合条件的地区该显示.
设计封装类:
基于前面的分析,适配器的绑定数据肯定要用到封装类,所以先把这事办了:
package com.sdxzt.xueliangapp_v2.video_monitor_page;
/**
* 封装区域对象,三种属性,名字/自身id/父级区域id
*/
public class SpinnerBean {
private String name;
private int id;
private int parentId;
public SpinnerBean(String name, int id, int parentId) {
this.name = name;
this.id = id;
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
}
BaseAdapter的常用需重写方法:
在进入正题前,先列举一下这个类的方法,这些方法大多是回调函数,因为会用到,而又不熟悉.总结一下
- int getCount() 返回列表的数量,这里就是根据地区列表的size来决定
- Object getItem(int i) 根据指定的位置返回索引位的数据对象
- long getItemId():根据指定的索引位返回指定条目对应的行号;
- View getView(int i, View view, ViewGroup viewGroup):
- 在一般列表中,当绘制列表中的每一个条目时自动调用的方法,绘制多少个条目就会调用多少次;
- 在spinner中,这个方法是绘制列表合起来的时候显示列表,只有一行.另一个方法是下面这个
- View getDropDownView(int position, View convertView, ViewGroup parent)
这个方法是绘制列表打开时,打开的那个表中的每一个条目,绘制多少个就调用多少次.与上面这个方法是分开的 - class ViewHolder 这是个内部类,用来封装当前列表一个条目所有的的布局子控件,一般用来绑定在view中,以便只赋值一次,多次使用,提高效率
不同颜色的设置
看了上面的方法作用自然就明白了,getView和getDropDownView是分别针对打开和未打开的列表,对样式的设置,自然在这两个方法里.
-
首行显示红色,只需在getView里为TextView控件设置颜色即可
-
打开后,已选择的条目显示红色,这里就需要在绘制每个条目时判断这个position是否被选中,那么就要定义一个变量,判断它和当前position是否相等.这个变量的值可以spinner的OnItemSelected监听器触发时传进来.
-
SpinnerAdapter.java
package com.sdxzt.xueliangapp_v2.video_monitor_page;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import andr