package cn.qqtheme.framework.picker;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
import cn.qqtheme.framework.entity.City;
import cn.qqtheme.framework.entity.County;
import cn.qqtheme.framework.entity.Province;
import cn.qqtheme.framework.util.LogUtils;
import cn.qqtheme.framework.widget.WheelView;
/**
* 地址选择器(包括省级、地级、县级),地址数据见示例项目assets目录下。
* “assets/city.json”转换自国家统计局(http://www.stats.gov.cn/tjsj/tjbz/xzqhdm)
* “assets/area.db”来源于开源项目(https://github.com/chihane/JDAddressSelector)
*
* @author 李玉江[QQ:1032694760]
* @see Province
* @see City
* @see County
* @since 2015/12/15, 2016/12/18
*/
public class AddressPicker extends LinkagePicker<Province, City, County> {
private OnAddressPickListener onAddressPickListener;
private OnWheelListener onWheelListener;
//只显示地市及区县
private boolean hideProvince = false;
//只显示省份及地市
private boolean hideCounty = false;
//省市区数据
private ArrayList<Province> provinces = new ArrayList<>();
public AddressPicker(Activity activity, ArrayList<Province> provinces) {
super(activity, new AddressProvider(provinces));
this.provinces = provinces;
}
/**
* 设置默认选中的省市县
*/
public void setSelectedItem(Province province, City city, County county) {
super.setSelectedItem(province, city, county);
}
public void setSelectedItem(String province, String city, String county) {
setSelectedItem(new Province(province), new City(city), new County(county));
}
public Province getSelectedProvince() {
return provinces.get(selectedFirstIndex);
}
public City getSelectedCity() {
List<City> cities = getSelectedProvince().getCities();
if (cities.size() == 0) {
return null;//可能没有第二级数据
}
return cities.get(selectedSecondIndex);
}
public County getSelectedCounty() {
List<County> counties = getSelectedCity().getCounties();
if (counties.size() == 0) {
return null;//可能没有第三级数据
}
return counties.get(selectedThirdIndex);
}
/**
* 隐藏省级行政区,只显示地市级和区县级。
* 设置为true的话,地址数据中只需要某个省份的即可
* 参见示例中的“assets/city2.json”
*/
public void setHideProvince(boolean hideProvince) {
this.hideProvince = hideProvince;
}
/**
* 隐藏县级行政区,只显示省级和市级。
* 设置为true的话,hideProvince将强制为false
* 数据源依然使用“assets/city.json” 仅在逻辑上隐藏县级选择框,实际项目中应该去掉县级数据。
*/
public void setHideCounty(boolean hideCounty) {
this.hideCounty = hideCounty;
}
/**
* 设置滑动监听器
*/
public void setOnWheelListener(OnWheelListener onWheelListener) {
this.onWheelListener = onWheelListener;
}
public void setOnAddressPickListener(OnAddressPickListener listener) {
this.onAddressPickListener = listener;
}
/**
* @deprecated use {@link #setOnAddressPickListener(OnAddressPickListener)} instead
*/
@Deprecated
@Override
public final void setOnLinkageListener(OnLinkageListener onLinkageListener) {
throw new UnsupportedOperationException("Please use setOnAddressPickListener instead.");
}
@NonNull
@Override
protected View makeCenterView() {
if (null == provider) {
throw new IllegalArgumentException("please set address provider before make view");
}
float provinceWeight = firstColumnWeight;
float cityWeight = secondColumnWeight;
float countyWeight = thirdColumnWeight;
if (hideCounty) {
hideProvince = false;
}
if (hideProvince) {
provinceWeight = 0;
cityWeight = firstColumnWeight;
countyWeight = secondColumnWeight;
}
dividerConfig.setRatio(WheelView.DividerConfig.FILL);
LinearLayout layout = new LinearLayout(activity);
layout.setOrientation(LinearLayout.HORIZONTAL);
layout.setGravity(Gravity.CENTER);
final WheelView provinceView = createWheelView();
provinceView.setUseWeight(true);
provinceView.setLayoutParams(new LinearLayout.LayoutParams(0, WRAP_CONTENT, provinceWeight));
layout.addView(provinceView);
if (hideProvince) {
provinceView.setVisibility(View.GONE);
}
final WheelView cityView = createWheelView();
cityView.setUseWeight(true);
cityView.setLayoutParams(new LinearLayout.LayoutParams(0, WRAP_CONTENT, cityWeight));
layout.addView(cityView);
final WheelView countyView = createWheelView();
countyView.setUseWeight(true);
countyView.setLayoutParams(new LinearLayout.LayoutParams(0, WRAP_CONTENT, countyWeight));
layout.addView(countyView);
if (hideCounty) {
countyView.setVisibility(View.GONE);
}
provinceView.setItems(provider.initFirstData(), selectedFirstIndex);
provinceView.setOnItemSelectListener(new WheelView.OnItemSelectListener() {
@Override
public void onSelected(int index) {
selectedFirstIndex = index;
selectedFirstItem = getSelectedProvince();
if (onWheelListener != null) {
onWheelListener.onProvinceWheeled(selectedFirstIndex, selectedFirstItem);
}
LogUtils.verbose(this, "change cities after province wheeled: index=" + index);
selectedSecondIndex = 0;//重置地级索引
selectedThirdIndex = 0;//重置县级索引
//根据省份获取地市
//noinspection unchecked
List<City> cities = provider.linkageSecondData(selectedFirstIndex);
if (cities.size() > 0) {
selectedSecondItem = cities.get(selectedSecondIndex);
cityView.setItems(cities, selectedSecondIndex);
} else {
selectedSecondItem = null;
cityView.setItems(new ArrayList<String>());
}
//根据地市获取区县
//noinspection unchecked
List<County> counties = provider.linkageThirdData(selectedFirstIndex, selectedSecondIndex);
if (counties.size() > 0) {
selectedThirdItem = counties.get(selectedThirdIndex);
countyView.setItems(counties, selectedThirdIndex);
} else {
selectedThirdItem = null;
countyView.setItems(new ArrayList<String>());
}
}
});
cityView.setItems(provider.linkageSecondData(selectedFirstIndex), selectedSecondIndex);
cityView.setOnItemSelectListener(new WheelView.OnItemSelectListener() {
@Override
public void onSelected(int index) {
selectedSecondIndex = index;
selectedSecondItem = getSelectedCity();
if (onWheelListener != null) {
onWheelListener.onCityWheeled(selectedSecondIndex, selectedSecondItem);
}
LogUtils.verbose(this, "change counties after city wheeled: index=" + index);
selectedThirdIndex = 0;//重置县级索引
//根据地市获取区县
//noinspection unchecked
List<County> counties = provider.linkageThirdData(selectedFirstIndex, selectedSecondIndex);
if (counties.size() > 0) {
selectedThirdItem = counties.get(selectedThirdIndex);
//若不是用户手动滚动,说明联动需要指定默认项
countyView.setItems(counties, selectedThirdIndex);
} else {
selectedThirdItem = null;
countyView.setItems(new ArrayList<String>());
}
}
});
countyView.setItems(provider.linkageThirdData(selectedFirstIndex, selectedSecondIndex), selectedThirdIndex);
countyView.setOnItemSelectListener(new WheelView.OnItemSelectListener() {
@Override
public void onSelected(int index) {
selectedThirdIndex = index;
selectedThirdItem = getSelectedCounty();
if (onWheelListener != null) {
onWheelListener.onCountyWheeled(selectedThirdIndex, selectedThirdItem);
}
}
});
return layout;
}
@Override
public void onSubmit() {
if (onAddressPickListener != null) {
Province province = getSelectedProvince();
City city = getSelectedCity();
County county = null;
if (!hideCounty) {
county = getSelectedCounty();
}
onAddressPickListener.onAddressPicked(province, city, county);
}
}
/**
* 地址选择回调
*/
public interface OnAddressPickListener {
void onAddressPicked(Province province, City city, County county);
}
/**
* 滑动回调
*/
public interface OnWheelListener {
void onProvinceWheeled(int index, Province province);
void onCityWheeled(int index, City city);
void onCountyWheeled(int index, County county);
}
/**
* 地址提供者
*/
private static class AddressProvider implements Provider<Province, City, County> {
private List<Province> firstList = new ArrayList<>();
private List<List<City>> secondList = new ArrayList<>();
private List<List<List<County>>> thirdList = new ArrayList<>();
public AddressProvider(List<Province> provinces) {
parseData(provinces);
}
@Override
public boolean isOnlyTwo() {
return thirdList.size() == 0;
}
@Override
@NonNull
public List<Province> initFirstData() {
return firstList;
}
@Override
@NonNull
public List<City> linkageSecondData(int firstIndex) {
return secondList.get(firstIndex);
}
@Override
@NonNull
public List<County> linkageThirdData(int firstIndex, int secondIndex) {
return thirdList.get(firstIndex).get(secondIndex);
}
private void parseData(List<Province> data) {
int provinceSize = data.size();
//添加省
for (int x = 0; x < provinceSize; x++) {
Province pro = data.get(x);
firstList.add(pro);
List<City> cities = pro.getCities();
List<City> xCities = new ArrayList<>();
List<List<County>> xCounties = new ArrayList<>();
int citySize = cities.size();
//添加地市
for (int y = 0; y < citySize; y++) {
City cit = cities.get(y);
cit.setProvinceId(pro.getAreaId());
xCities.add(cit);
List<County> counties = cit.getCounties();
ArrayList<County> yCounties = new ArrayList<>();
int countySize = counties.size();
//添加区县
for (int z = 0; z < countySize; z++) {
County cou = counties.get(z);
cou.setCityId(cit.getAreaId());
yCounties.add(cou);
}
xCounties.add(yCounties);
}
secondList.add(xCities);
thirdList.add(xCounties);
}
}
}
}