由于时间关系废话不多说了,直接上这次我想要实现的效果图。
这边博客的最终效果图如下所示。总共有三个下拉框,刚开始只显示出第一个下拉框出来,每选择完一个下拉框就会显示出下个下拉出来。如果将第一个下拉框设置为请选择,则第二三个下拉框边为不可见。如果同理,将第二个下拉看设置为请选择,则第三个下拉框也要设置为不可见。大概就这样。
看看项目结构,三个java文件,两个布局文件。
1、创建一个Bean类DrowSpinnerBean.java,由于在下拉框列表中需要显示一张图片,和一个标题。因此这个类只需要两个字段,一个ImgId字段用来存放图片,一个title字段用来存放标题。
2、说说自定义Spinner思路,数据源->适配器->控件(Spinner)显示。首先创建一个java文件命名为CustomSpinnerAdapter,接着需要重写BaseAdapter类(需要覆盖四个方法getCount(),getItem(),getItemId(),getView()),在里面自定义下拉框中每个Item的布局和数据绑定。
完整代码请戳这里Android城市级联下拉框(自定义Spinner)
看看项目结构,三个java文件,两个布局文件。
1、创建一个Bean类DrowSpinnerBean.java,由于在下拉框列表中需要显示一张图片,和一个标题。因此这个类只需要两个字段,一个ImgId字段用来存放图片,一个title字段用来存放标题。
package sms.edward.per.myapplication;
/**
* description:Bean类
* <p/>
* author:Edward
* <p/>
* 2015/10/11
*/
public class DrowSpinnerBean {
private int imgId;
private String title;
public int getImgId() {
return imgId;
}
public void setImgId(int imgId) {
this.imgId = imgId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
2、说说自定义Spinner思路,数据源->适配器->控件(Spinner)显示。首先创建一个java文件命名为CustomSpinnerAdapter,接着需要重写BaseAdapter类(需要覆盖四个方法getCount(),getItem(),getItemId(),getView()),在里面自定义下拉框中每个Item的布局和数据绑定。
package sms.edward.per.myapplication;
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;
import java.util.List;
/**
* description:Spinner适配器
* <p/>
* author:Edward
* <p/>
* 2015/10/11
*/
public class CustomSpinnerAdapter extends BaseAdapter {
private List<sms.edward.per.myapplication.DrowSpinnerModel> list;
private int layoutId;
private Context context;
public CustomSpinnerAdapter(Context context, List<sms.edward.per.myapplication.DrowSpinnerModel> list, int layoutId) {
this.context = context;
this.layoutId = layoutId;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder = null;
if (view == null) {
viewHolder = new ViewHolder();
//加载item布局
view = LayoutInflater.from(context).inflate(layoutId, null);
//获取实例化
viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view);
viewHolder.textView = (TextView) view.findViewById(R.id.txt_view);
//保存实例化的控件
view.setTag(viewHolder);
} else {
//重新获取实例化的控件
viewHolder = (ViewHolder) view.getTag();
}
//绑定数据
viewHolder.imageView.setBackgroundResource(list.get(i).getImgId());
viewHolder.textView.setText(list.get(i).getTitle());
return view;
}
public class ViewHolder {
ImageView imageView;
TextView textView;
}
}
在屏幕滑动的过程中,最顶部或最底部的Item由可见状态转变为不可见状态的时候都会回调getView方法。获取原来的Item里面的控件将其重新绑上数据。具体绘制原理请各位搜索一下吧。
3、设置好适配器之后,我们需要再写一个适配器的布局文件,将这个文件命名为activity_item.xml
4、做好适配器的工作之后,就开始设置主页面的布局,创建一个布局文件,文件名为activity_main.xml,在一个线性布局中放三个Spinner
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#ffffff"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_view"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:background="@mipmap/ic_launcher" />
<TextView
android:id="@+id/txt_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/image_view"
android:text="测试" />
</RelativeLayout>
很简单的一个布局,效果如图所示。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#ffffff"
android:layout_height="match_parent"
android:orientation="horizontal">
<Spinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown" />
<Spinner
android:id="@+id/spinner2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown"
android:visibility="invisible" />
<Spinner
android:id="@+id/spinner3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown"
android:visibility="invisible" />
</LinearLayout>
这里需要特别说明的是visibility属性的三个参数:VISIBLE(可见),INVISIBLE(不可见,但会占据位置),GONE(不可见,不会占据位置)
5、设置主布局的代码,创建一个MainActivity.java文件。在这个文件之中创建了三个List<DrowSpinnerBean>用来存放数据。将主要的逻辑操作都放在Spinner的监听器事件里面。具体请看代码注释。
最终的效果图跟开头的git动画一样。package sms.edward.per.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* 此Demo博客地址:http://blog.csdn.net/u012814441/article/details/49073457
* <p/>
* author:Edward
*/
public class MainActivity extends Activity {
private List<DrowSpinnerBean> list1;
private List<DrowSpinnerBean> list2;
private List<DrowSpinnerBean> list3;
private Spinner spinner1, spinner2, spinner3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner1 = (Spinner) findViewById(R.id.spinner1);
spinner2 = (Spinner) findViewById(R.id.spinner2);
spinner3 = (Spinner) findViewById(R.id.spinner3);
//加载省份列表
loadProvince();
//设置点击事件
spinner1.setOnItemSelectedListener(new Spinner1ClickListener());
//加载城市列表
loadCity();
//设置点击事件
spinner2.setOnItemSelectedListener(new Spinner2ClickListener());
//加载区域列表
loadGZArea();
//设置点击事件
spinner3.setOnItemSelectedListener(new Spinner3ClickListener());
}
/**
* 加载省份
*/
public void loadProvince() {
list1 = new ArrayList<>();
DrowSpinnerBean modelOne;
modelOne = new DrowSpinnerBean();
modelOne.setImgId(R.mipmap.edward1);
modelOne.setTitle("请选择");
list1.add(modelOne);
modelOne = new DrowSpinnerBean();
modelOne.setImgId(R.mipmap.edward15);
modelOne.setTitle("广东省");
list1.add(modelOne);
CustomSpinnerAdapter adapterOne = new CustomSpinnerAdapter(this, list1, R.layout.activity_item);
spinner1.setAdapter(adapterOne);
}
/**
* 加载城市列表
*/
public void loadCity() {
list2 = new ArrayList<>();
DrowSpinnerBean modelTwo;
modelTwo = new DrowSpinnerBean();
modelTwo.setImgId(R.mipmap.edward1);
modelTwo.setTitle("请选择");
list2.add(modelTwo);
modelTwo = new DrowSpinnerBean();
modelTwo.setImgId(R.mipmap.edward15);
modelTwo.setTitle("广州市");
list2.add(modelTwo);
modelTwo = new DrowSpinnerBean();
modelTwo.setImgId(R.mipmap.edward15);
modelTwo.setTitle("深圳市");
list2.add(modelTwo);
CustomSpinnerAdapter adapterTwo = new CustomSpinnerAdapter(this, list2, R.layout.activity_item);
spinner2.setAdapter(adapterTwo);
}
/**
* 加载广州区域列表
*/
public void loadGZArea() {
list3 = new ArrayList<>();
DrowSpinnerBean modelThree;
modelThree = new DrowSpinnerBean();
modelThree.setImgId(R.mipmap.edward1);
modelThree.setTitle("请选择");
list3.add(modelThree);
modelThree = new DrowSpinnerBean();
modelThree.setImgId(R.mipmap.edward15);
modelThree.setTitle("天河区");
list3.add(modelThree);
modelThree = new DrowSpinnerBean();
modelThree.setImgId(R.mipmap.edward15);
modelThree.setTitle("越秀区");
list3.add(modelThree);
CustomSpinnerAdapter adapterThree = new CustomSpinnerAdapter(this, list3, R.layout.activity_item);
spinner3.setAdapter(adapterThree);
}
/**
* 加载深圳区域列表
*/
public void loadSZArea() {
list3 = new ArrayList<>();
DrowSpinnerBean modelThree = null;
modelThree = new DrowSpinnerBean();
modelThree.setImgId(R.mipmap.edward15);
modelThree.setTitle("请选择");
list3.add(modelThree);
modelThree = new DrowSpinnerBean();
modelThree.setImgId(R.mipmap.edward15);
modelThree.setTitle("龙岗区");
list3.add(modelThree);
modelThree = new DrowSpinnerBean();
modelThree.setImgId(R.mipmap.edward15);
modelThree.setTitle("南山区");
list3.add(modelThree);
CustomSpinnerAdapter adapterThree = new CustomSpinnerAdapter(MainActivity.this, list3, R.layout.activity_item);
spinner3.setAdapter(adapterThree);
}
/**
* Spinner1点击事件
*/
public class Spinner1ClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);
//判断是否选择城市,如果没有选择那么就隐藏Spinner2,Spinner3两个下拉框,否则显示Spinner2下拉框,继续隐藏Spinner3
if (model.getTitle().equals("请选择")) {
spinner2.setVisibility(View.INVISIBLE);
spinner3.setVisibility(View.INVISIBLE);
} else {
spinner2.setVisibility(View.VISIBLE);
//将第二个下拉框的选项重新设置为选中“请选择”这个选项。
spinner2.setSelection(0);
}
Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
/**
* Spinner2点击事件
*/
public class Spinner2ClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);
if (model.getTitle().equals("请选择")) {
spinner3.setVisibility(View.INVISIBLE);
} else {
//显示第三个Spinner3
spinner3.setVisibility(View.VISIBLE);
if (model.getTitle().equals("深圳市")) {
//重新加载深圳区域列表
loadSZArea();
} else if (model.getTitle().equals("广州市")) {
//重新加载广州区域列表
loadGZArea();
}
}
Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
/**
* Spinner3点击事件
*/
public class Spinner3ClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);
Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
}
完整代码请戳这里Android城市级联下拉框(自定义Spinner)