很早之前看淘宝就有了ios那种的城市选择控件,当时也看到网友有分享,不过那个写的很烂,后来(大概是去年吧),我们公司有这么一个项目,当时用的还是网上比较流行的那个黑框的那个,感觉特别的丑,然后我在那个开源的wheelview的基础上做封装,用户只需要专心数据的组装即可,然后填充就行,其他的可以不必考虑。
先上下效果图
接下来说下我的思路:网络请求-数据返回-设置数据-数据填充控件
接下来直接按上面的流程直接上代码:
网络请求我用的本地的json数据
String address = Utils.readAssert(this, "address.txt");
AddressModel model = JsonUtil.parseJson(address, AddressModel.class);
然后我们将本地的数据通过InputStream转换为String,并用过Gson将String映射到Model对象中
<span style="font-size:18px;"> public static String readAssert(Context context, String fileName){
String jsonString="";
String resultString="";
try {
InputStream inputStream=context.getResources().getAssets().open(fileName);
byte[] buffer=new byte[inputStream.available()];
inputStream.read(buffer);
resultString=new String(buffer,"utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}</span>
接下来我们写自定义的Popwindos实现选择城市的弹框
<span style="font-size:18px;">public class ChooseAddressWheel implements MyOnWheelChangedListener {
@Bind(R.id.province_wheel)
MyWheelView provinceWheel;
@Bind(R.id.city_wheel)
MyWheelView cityWheel;
@Bind(R.id.district_wheel)
MyWheelView districtWheel;
private Activity context;
private View parentView;
private PopupWindow popupWindow = null;
private WindowManager.LayoutParams layoutParams = null;
private LayoutInflater layoutInflater = null;
private List<AddressDtailsEntity.ProvinceEntity> province = null;
private OnAddressChangeListener onAddressChangeListener = null;
public ChooseAddressWheel(Activity context) {
this.context = context;
init();
}
private void init() {
layoutParams = context.getWindow().getAttributes();
layoutInflater = context.getLayoutInflater();
initView();
initPopupWindow();
}
private void initView() {
parentView = layoutInflater.inflate(R.layout.choose_city_layout, null);
ButterKnife.bind(this, parentView);
provinceWheel.setVisibleItems(7);
cityWheel.setVisibleItems(7);
districtWheel.setVisibleItems(7);
provinceWheel.addChangingListener(this);
cityWheel.addChangingListener(this);
districtWheel.addChangingListener(this);
}
private void initPopupWindow() {
popupWindow = new PopupWindow(parentView, WindowManager.LayoutParams.MATCH_PARENT, (int) (Utils.getScreenHeight(context) * (2.0 / 5)));
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popupWindow.setAnimationStyle(R.style.anim_push_bottom);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setOutsideTouchable(false);
popupWindow.setFocusable(true);
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
public void onDismiss() {
layoutParams.alpha = 1.0f;
context.getWindow().setAttributes(layoutParams);
popupWindow.dismiss();
}
});
}
private void bindData() {
provinceWheel.setViewAdapter(new ProvinceWheelAdapter(context, province));
updateCitiy();
updateDistrict();
}
@Override
public void onChanged(MyWheelView wheel, int oldValue, int newValue) {
if (wheel == provinceWheel) {
updateCitiy();//省份改变后城市和地区联动
} else if (wheel == cityWheel) {
updateDistrict();//城市改变后地区联动
} else if (wheel == districtWheel) {
}
}
private void updateCitiy() {
int index = provinceWheel.getCurrentItem();
List<AddressDtailsEntity.ProvinceEntity.CityEntity> citys = province.get(index).City;
if (citys != null && citys.size() > 0) {
cityWheel.setViewAdapter(new CityWheelAdapter(context, citys));
cityWheel.setCurrentItem(0);
updateDistrict();
}
}
private void updateDistrict() {
int provinceIndex = provinceWheel.getCurrentItem();
List<ProvinceEntity.CityEntity> citys = province.get(provinceIndex).City;
int cityIndex = cityWheel.getCurrentItem();
List<ProvinceEntity.AreaEntity> districts = citys.get(cityIndex).Area;
if (districts != null && districts.size() > 0) {
districtWheel.setViewAdapter(new AreaWheelAdapter(context, districts));
districtWheel.setCurrentItem(0);
}
}
public void show(View v) {
layoutParams.alpha = 0.6f;
context.getWindow().setAttributes(layoutParams);
popupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
}
public void setProvince(List<ProvinceEntity> province) {
this.province = province;
bindData();
}
public void defaultValue(String provinceStr, String city, String arae) {
if (TextUtils.isEmpty(provinceStr)) return;
for (int i = 0; i < province.size(); i++) {
ProvinceEntity provinces = province.get(i);
if (provinces != null && provinces.Name.equalsIgnoreCase(provinceStr)) {
provinceWheel.setCurrentItem(i);
if (TextUtils.isEmpty(city)) return;
List<ProvinceEntity.CityEntity> citys = provinces.City;
for (int j = 0; j < citys.size(); j++) {
ProvinceEntity.CityEntity cityEntity = citys.get(j);
if (cityEntity != null && cityEntity.Name.equalsIgnoreCase(city)) {
cityWheel.setViewAdapter(new CityWheelAdapter(context, citys));
cityWheel.setCurrentItem(j);
if (TextUtils.isEmpty(arae)) return;
List<ProvinceEntity.AreaEntity> areas = cityEntity.Area;
for (int k = 0; k < areas.size(); k++) {
ProvinceEntity.AreaEntity areaEntity = areas.get(k);
if (areaEntity != null && areaEntity.Name.equalsIgnoreCase(arae)) {
districtWheel.setViewAdapter(new AreaWheelAdapter(context, areas));
districtWheel.setCurrentItem(k);
}
}
}
}
}
}
}
@OnClick(R.id.confirm_button)
public void confirm() {
if (onAddressChangeListener != null) {
int provinceIndex = provinceWheel.getCurrentItem();
int cityIndex = cityWheel.getCurrentItem();
int areaIndex = districtWheel.getCurrentItem();
String provinceName = null, cityName = null, areaName = null;
List<ProvinceEntity.CityEntity> citys = null;
if (province != null && province.size() > provinceIndex) {
ProvinceEntity provinceEntity = province.get(provinceIndex);
citys = provinceEntity.City;
provinceName = provinceEntity.Name;
}
List<ProvinceEntity.AreaEntity> districts = null;
if (citys != null && citys.size() > cityIndex) {
ProvinceEntity.CityEntity cityEntity = citys.get(cityIndex);
districts = cityEntity.Area;
cityName = cityEntity.Name;
}
if (districts != null && districts.size() > areaIndex) {
ProvinceEntity.AreaEntity areaEntity = districts.get(areaIndex);
areaName = areaEntity.Name;
}
onAddressChangeListener.onAddressChange(provinceName, cityName, areaName);
}
cancel();
}
@OnClick(R.id.cancel_button)
public void cancel() {
popupWindow.dismiss();
}
public void setOnAddressChangeListener(OnAddressChangeListener onAddressChangeListener) {
this.onAddressChangeListener = onAddressChangeListener;
}</span>
然后通过三个Adapter去设置值,这里展示一个
<span style="font-size:18px;">public class ProvinceWheelAdapter extends BaseWheelAdapter<AddressDtailsEntity.ProvinceEntity> {
public ProvinceWheelAdapter(Context context, List<AddressDtailsEntity.ProvinceEntity> list) {
super(context,list);
}
@Override
protected CharSequence getItemText(int index) {
AddressDtailsEntity.ProvinceEntity data = getItemData(index);
if(data != null){
return data.Name;
}
return null;
}
}</span>
那么在我们的页面中我们怎么用呢?
我们先初始化:
<span style="font-size:18px;">private void init() {
initWheel();
initData();
}</span>
<span style="font-size:18px;">private void initWheel() {
chooseAddressWheel = new ChooseAddressWheel(this);
chooseAddressWheel.setOnAddressChangeListener(this);
}</span>
接下来设置值了
<span style="font-size:18px;">private void initData() {
String address = Utils.readAssert(this, "address.txt");
AddressModel model = JsonUtil.parseJson(address, AddressModel.class);
if (model != null) {
AddressDtailsEntity data = model.Result;
if (data == null) return;
chooseAddress.setText(data.Province + " " + data.City + " " + data.Area);
if (data.ProvinceItems != null && data.ProvinceItems.Province != null) {
chooseAddressWheel.setProvince(data.ProvinceItems.Province);
chooseAddressWheel.defaultValue(data.Province, data.City, data.Area);
}
}
}</span>
好了,就写到这里了,有需要的请加我们的群:278792776或者188716429
最后附上代码下载地址: