最近项目中需要用到地址选择器,一开始为了节省时间打算网上找个现成的。但是效果都不太好,首先数据和有点不一样。所以打算自己写个简单的。先来看看实现效果:
大家也发现了应该,标题一直是北京市,忘记改了。不过都不要紧,基本功能都有了。
界面很简单,首先这个地址选择器是用popupwindow来做的。直接来看自定义的popupwindow:
package zjlskj.com.dqwlee.pop;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.List;
import zjlskj.com.dqwlee.R;
import zjlskj.com.dqwlee.tools.L;
import zjlskj.com.dqwlee.tools.T;
import zjlskj.com.dqwlee.tools.cityTools.Address;
import zjlskj.com.dqwlee.tools.cityTools.AddressTools;
import zjlskj.com.dqwlee.tools.cityTools.City;
import zjlskj.com.dqwlee.tools.cityTools.District;
import zjlskj.com.dqwlee.tools.cityTools.Province;
/**
* Created by 韦鹏飞 on 2016/1/19.
*/
public class AddressPop extends PopupWindow implements View.OnClickListener {
View conentView;
private Context context;
private GridView gd; //用于显示地区
private List<Province> provinces;
private ProvinceAdapter adapter;
private OnAddressCheckedListener listener = null; //回调接口
private List currentLists;//当前省市县其中的一个集合
private ImageButton vBack;
private String currentProvince;
private String currentCity;
private String currentDistrict;
public AddressPop(Activity context) {
this.context = context;
conentView = View.inflate(context, R.layout.pop_address_select, null);
int h = context.getWindowManager().getDefaultDisplay().getHeight();
int w = context.getWindowManager().getDefaultDisplay().getWidth();
// 设置SelectPicPopupWindow的View
this.setContentView(conentView);
// 设置SelectPicPopupWindow弹出窗体的宽
this.setWidth(w);
// 设置SelectPicPopupWindow弹出窗体的高
this.setHeight(h / 3 * 2);
// 设置SelectPicPopupWindow弹出窗体可点击
this.setFocusable(true);
this.setOutsideTouchable(true);
// 刷新状态
this.update();
// 实例化一个ColorDrawable颜色为半透明
ColorDrawable dw = new ColorDrawable(0000000000);
// 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作
this.setBackgroundDrawable(dw);
this.setAnimationStyle(R.style.bottomShow);
init();
setListener();
}
private void init() {
vBack = (ImageButton) conentView.findViewById(R.id.ib_back);
adapter = new ProvinceAdapter();
provinces = AddressTools.getProvinces();
currentLists = provinces;
gd = (GridView) conentView.findViewById(R.id.gv);
gd.setAdapter(adapter);
}
private void setListener(){
vBack.setOnClickListener(this);
}
public void setAddressListener(OnAddressCheckedListener listener) {
this.listener = listener;
}
/**
* 地址选择后回调接口
*/
public interface OnAddressCheckedListener {
void onAddressChecked(String province, String city, String district);
}
private String TAG = "PROVINCE";
Province province;
City city;
District district;
Address address;
class ProvinceAdapter extends BaseAdapter {
@Override
public int getCount() {
return currentLists.size();
}
@Override
public Object getItem(int position) {
return currentLists.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
address = (Address) currentLists.get(position);
ViewHolder holder = null;
if (convertView == null) {
convertView = View.inflate(context, R.layout.gridview_adderss, null);
holder = new ViewHolder();
holder.btn = (Button) convertView.findViewById(R.id.btn);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btn.setText(address.getName());
holder.btn.setTag(position);
holder.btn.setOnClickListener(AddressPop.this);
return convertView;
}
}
static class ViewHolder {
Button btn;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
enterAddress(v);
break;
case R.id.ib_back:
back();
break;
}
}
/**
* 点击省市县item
* @param v
*/
private void enterAddress(View v){
int position = (int) v.getTag();
if (TAG.equals("PROVINCE")) {
TAG = "CITY";
province = (Province) currentLists.get(position);
currentProvince = province.getName();
T.showShort(context,currentProvince);
currentLists = AddressTools.getCitysByProvinces(province);
} else if (TAG.equals("CITY")) {
TAG = "DISTRICT";
city = (City) currentLists.get(position);
currentCity = city.getName();
currentLists = AddressTools.getDistrictByCity(city);
if(currentLists.size() == 0){
TAG = "PROVINCE";
currentLists = AddressTools.getProvinces();
dismiss();
}
T.showShort(context,currentCity);
} else if(TAG =="DISTRICT"){
TAG = "PROVINCE";
district = (District) currentLists.get(position);
currentDistrict = district.getName();
currentLists = AddressTools.getProvinces();
dismiss();
T.showShort(context, currentDistrict);
}
adapter.notifyDataSetChanged();
}
private void back(){
if (TAG.equals("PROVINCE")) {
currentProvince = "";
dismiss();
} else if (TAG.equals("CITY")) {
TAG = "PROVINCE";
currentCity="";
currentLists = AddressTools.getProvinces();
} else if(TAG =="DISTRICT"){
TAG = "CITY";
currentDistrict = "";
currentLists =AddressTools.getCitysByProvinces(province);
}
adapter.notifyDataSetChanged();
}
}
内容显示使用的是gridview。大致思路是,第一次打开默认显示省列表。然后每次点击item后获取当前省所有的城市,然后显示到gridview上。点击城市item获取所有县数据显示。省市县三个类都有getName()方法。由于我们要在同一个adapter的getview方法中获取相应对象并获取名字,所以我们创建一个Address类,提供getName方法并让省市县类继承自Address类,这样我们在getview中只要把对象转换成address对象然后getName()获取名字。每次点击item或者左上角返回键都设置TAG。具体的看demo。
还有popupwindow的动画可以在style中设置进入和退出的相应动画
ps:addressTools工具类可以获取省市县集合。
给新手提供一些思路。大神绕道。