taomenggo init
31
citypickerview/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.lljjcoder.style.citypickerview">
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name="com.lljjcoder.style.citylist.CityListSelectActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustNothing|stateUnchanged">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.lljjcoder.style.citythreelist.ProvinceActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustNothing|stateUnchanged">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.lljjcoder.style.citythreelist.CityActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustNothing|stateUnchanged">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.lljjcoder.style.citythreelist.AreaActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustNothing|stateUnchanged">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
2327
citypickerview/src/main/assets/china_city_data.json
Normal file
2327
citypickerview/src/main/assets/china_city_data_tw.json
Normal file
14
citypickerview/src/main/java/com/lljjcoder/Constant.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.lljjcoder;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2018/1/22 09:46
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class Constant {
|
||||
|
||||
public static final String CITY_DATA = "china_city_data.json";
|
||||
public static final String CITY_DATA_TW = "china_city_data_tw.json";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.lljjcoder.Interface;
|
||||
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/11/16 10:06
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public abstract class OnCityItemClickListener {
|
||||
|
||||
/**
|
||||
* 当选择省市区三级选择器时,需要覆盖此方法
|
||||
* @param province
|
||||
* @param city
|
||||
* @param district
|
||||
*/
|
||||
public void onSelected(ProvinceBean province, CityBean city, DistrictBean district) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
public void onCancel() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.lljjcoder.Interface;
|
||||
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.CustomCityData;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/11/16 10:06
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public abstract class OnCustomCityPickerItemClickListener {
|
||||
|
||||
/**
|
||||
* 当选择省市区三级选择器时,需要覆盖此方法
|
||||
*
|
||||
* @param province
|
||||
* @param city
|
||||
* @param district
|
||||
*/
|
||||
public void onSelected(CustomCityData province, CustomCityData city, CustomCityData district) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
public void onCancel() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.lljjcoder.bean;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @2Do:
|
||||
* @Author M2
|
||||
* @Version v ${VERSION}
|
||||
* @Date 2017/7/7 0007.
|
||||
*/
|
||||
public class CityBean implements Parcelable {
|
||||
|
||||
|
||||
private String id; /*110101*/
|
||||
|
||||
private String name; /*东城区*/
|
||||
|
||||
|
||||
private ArrayList<DistrictBean> cityList;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id == null ? "" : id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ArrayList<DistrictBean> getCityList() {
|
||||
return cityList;
|
||||
}
|
||||
|
||||
public void setCityList(ArrayList<DistrictBean> cityList) {
|
||||
this.cityList = cityList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.name);
|
||||
dest.writeTypedList(this.cityList);
|
||||
}
|
||||
|
||||
public CityBean() {
|
||||
}
|
||||
|
||||
protected CityBean(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.name = in.readString();
|
||||
this.cityList = in.createTypedArrayList(DistrictBean.CREATOR);
|
||||
}
|
||||
|
||||
public static final Creator<CityBean> CREATOR = new Creator<CityBean>() {
|
||||
@Override
|
||||
public CityBean createFromParcel(Parcel source) {
|
||||
return new CityBean(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CityBean[] newArray(int size) {
|
||||
return new CityBean[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.lljjcoder.bean;
|
||||
|
||||
public class CityJson {
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.lljjcoder.bean;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义数据源需要的数据model,自定义的话需要继承该数据model
|
||||
*/
|
||||
public class CustomCityData {
|
||||
private String id; /*110101*/
|
||||
|
||||
private String name; /*东城区*/
|
||||
|
||||
private List<CustomCityData> list = new ArrayList<>();
|
||||
|
||||
public CustomCityData() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CustomCityData(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<CustomCityData> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<CustomCityData> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.lljjcoder.bean;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* @2Do:
|
||||
* @Author M2
|
||||
* @Version v ${VERSION}
|
||||
* @Date 2017/7/7 0007.
|
||||
*/
|
||||
public class DistrictBean implements Parcelable {
|
||||
|
||||
private String id; /*110101*/
|
||||
|
||||
private String name; /*东城区*/
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id == null ? "" : id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.name);
|
||||
}
|
||||
|
||||
public DistrictBean() {
|
||||
}
|
||||
|
||||
protected DistrictBean(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.name = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<DistrictBean> CREATOR = new Creator<DistrictBean>() {
|
||||
@Override
|
||||
public DistrictBean createFromParcel(Parcel source) {
|
||||
return new DistrictBean(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistrictBean[] newArray(int size) {
|
||||
return new DistrictBean[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.lljjcoder.bean;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @2Do:
|
||||
* @Author M2
|
||||
* @Version v ${VERSION}
|
||||
* @Date 2017/7/7 0007.
|
||||
*/
|
||||
public class ProvinceBean implements Parcelable {
|
||||
|
||||
private String id; /*110101*/
|
||||
|
||||
private String name; /*东城区*/
|
||||
|
||||
|
||||
private ArrayList<CityBean> cityList;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name ;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id == null ? "" : id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ArrayList<CityBean> getCityList() {
|
||||
return cityList;
|
||||
}
|
||||
|
||||
public void setCityList(ArrayList<CityBean> cityList) {
|
||||
this.cityList = cityList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.name);
|
||||
dest.writeTypedList(this.cityList);
|
||||
}
|
||||
|
||||
public ProvinceBean() {
|
||||
}
|
||||
|
||||
protected ProvinceBean(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.name = in.readString();
|
||||
this.cityList = in.createTypedArrayList(CityBean.CREATOR);
|
||||
}
|
||||
|
||||
public static final Creator<ProvinceBean> CREATOR = new Creator<ProvinceBean>() {
|
||||
@Override
|
||||
public ProvinceBean createFromParcel(Parcel source) {
|
||||
return new ProvinceBean(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProvinceBean[] newArray(int size) {
|
||||
return new ProvinceBean[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,848 @@
|
||||
package com.lljjcoder.citywheel;
|
||||
|
||||
/**
|
||||
* 城市选择器样式配置
|
||||
* 作者:liji on 2017/11/4 10:31
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityConfig {
|
||||
|
||||
public static final Integer NONE = -1111;
|
||||
|
||||
// private Context mContext;
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*/
|
||||
private int visibleItems = 5;
|
||||
|
||||
/**
|
||||
* 省滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isProvinceCyclic = true;
|
||||
|
||||
/**
|
||||
* 市滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isCityCyclic = true;
|
||||
|
||||
/**
|
||||
* 区滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isDistrictCyclic = true;
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelTextColorStr = "#000000";
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelText = "取消";
|
||||
|
||||
private int cancelTextSize = 16;
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmTextColorStr = "#0000FF";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmText = "确定";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private int confirmTextSize = 16;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String mTitle = "选择地区";
|
||||
|
||||
/**
|
||||
* 标题背景颜色
|
||||
*/
|
||||
private String titleBackgroundColorStr = "#E9E9E9";
|
||||
|
||||
/**
|
||||
* 标题颜色
|
||||
*/
|
||||
private String titleTextColorStr = "#585858";
|
||||
|
||||
/**
|
||||
* 标题字体大小
|
||||
*/
|
||||
private int titleTextSize = 18;
|
||||
|
||||
/**
|
||||
* 第一次默认的显示省份,一般配合定位,使用
|
||||
*/
|
||||
private String defaultProvinceName = "浙江";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示城市,一般配合定位,使用
|
||||
*/
|
||||
private String defaultCityName = "杭州";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示,一般配合定位,使用
|
||||
*/
|
||||
private String defaultDistrict = "滨江区";
|
||||
|
||||
/**
|
||||
* 自定义的item布局
|
||||
*/
|
||||
private Integer customItemLayout;
|
||||
|
||||
/**
|
||||
* 自定义的item txt id
|
||||
*/
|
||||
private Integer customItemTextViewId;
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*/
|
||||
private boolean drawShadows = true;
|
||||
|
||||
/**
|
||||
* 是否显示港澳台城市数据
|
||||
*/
|
||||
private boolean showGAT = false;
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
*/
|
||||
private String lineColor = "#C7C7C7";
|
||||
|
||||
/**
|
||||
* 中间线的宽度
|
||||
*/
|
||||
private int lineHeigh = 3;
|
||||
|
||||
|
||||
private int loclanguage = 0;
|
||||
|
||||
/**
|
||||
* 默认显示的城市数据,只包含省市区名称
|
||||
*/
|
||||
/**
|
||||
* 定义显示省市区三种滚轮的显示状态
|
||||
* PRO:只显示省份的一级选择器
|
||||
* PRO_CITY:显示省份和城市二级联动的选择器
|
||||
* PRO_CITY_DIS:显示省份和城市和县区三级联动的选择器
|
||||
*/
|
||||
public enum WheelType {
|
||||
PRO, PRO_CITY, PRO_CITY_DIS
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示半透明的背景
|
||||
*/
|
||||
private boolean isShowBackground = true;
|
||||
|
||||
/**
|
||||
* 定义默认显示省市区三级联动的滚轮选择器
|
||||
*/
|
||||
public WheelType mWheelType = WheelType.PRO_CITY_DIS;
|
||||
|
||||
public CityConfig.WheelType getWheelType() {
|
||||
return mWheelType;
|
||||
}
|
||||
|
||||
public boolean isShowBackground() {
|
||||
return isShowBackground;
|
||||
}
|
||||
|
||||
public boolean isShowGAT() {
|
||||
return showGAT;
|
||||
}
|
||||
|
||||
public void setShowGAT(boolean showGAT) {
|
||||
this.showGAT = showGAT;
|
||||
}
|
||||
|
||||
public String getLineColor() {
|
||||
return lineColor == null ? "" : lineColor;
|
||||
}
|
||||
|
||||
public void setLineColor(String lineColor) {
|
||||
this.lineColor = lineColor;
|
||||
}
|
||||
|
||||
public int getLineHeigh() {
|
||||
return lineHeigh;
|
||||
}
|
||||
|
||||
public void setLineHeigh(int lineHeigh) {
|
||||
this.lineHeigh = lineHeigh;
|
||||
}
|
||||
|
||||
public boolean isDrawShadows() {
|
||||
return drawShadows;
|
||||
}
|
||||
|
||||
public void setDrawShadows(boolean drawShadows) {
|
||||
this.drawShadows = drawShadows;
|
||||
}
|
||||
|
||||
public int getVisibleItems() {
|
||||
return visibleItems;
|
||||
}
|
||||
|
||||
public void setVisibleItems(int visibleItems) {
|
||||
this.visibleItems = visibleItems;
|
||||
}
|
||||
|
||||
public boolean isProvinceCyclic() {
|
||||
return isProvinceCyclic;
|
||||
}
|
||||
|
||||
public void setProvinceCyclic(boolean provinceCyclic) {
|
||||
isProvinceCyclic = provinceCyclic;
|
||||
}
|
||||
|
||||
public boolean isCityCyclic() {
|
||||
return isCityCyclic;
|
||||
}
|
||||
|
||||
public void setCityCyclic(boolean cityCyclic) {
|
||||
isCityCyclic = cityCyclic;
|
||||
}
|
||||
|
||||
public boolean isDistrictCyclic() {
|
||||
return isDistrictCyclic;
|
||||
}
|
||||
|
||||
public void setDistrictCyclic(boolean districtCyclic) {
|
||||
isDistrictCyclic = districtCyclic;
|
||||
}
|
||||
|
||||
public String getCancelTextColorStr() {
|
||||
return cancelTextColorStr == null ? "" : cancelTextColorStr;
|
||||
}
|
||||
|
||||
public void setCancelTextColorStr(String cancelTextColorStr) {
|
||||
this.cancelTextColorStr = cancelTextColorStr;
|
||||
}
|
||||
|
||||
public String getCancelText() {
|
||||
return cancelText == null ? "" : cancelText;
|
||||
}
|
||||
|
||||
public void setCancelText(String cancelText) {
|
||||
this.cancelText = cancelText;
|
||||
}
|
||||
|
||||
public int getCancelTextSize() {
|
||||
return cancelTextSize;
|
||||
}
|
||||
|
||||
public void setCancelTextSize(int cancelTextSize) {
|
||||
this.cancelTextSize = cancelTextSize;
|
||||
}
|
||||
|
||||
public String getConfirmTextColorStr() {
|
||||
return confirmTextColorStr == null ? "" : confirmTextColorStr;
|
||||
}
|
||||
|
||||
public void setConfirmTextColorStr(String confirmTextColorStr) {
|
||||
this.confirmTextColorStr = confirmTextColorStr;
|
||||
}
|
||||
|
||||
public String getConfirmText() {
|
||||
return confirmText == null ? "" : confirmText;
|
||||
}
|
||||
|
||||
public void setConfirmText(String confirmText) {
|
||||
this.confirmText = confirmText;
|
||||
}
|
||||
|
||||
public int getConfirmTextSize() {
|
||||
return confirmTextSize;
|
||||
}
|
||||
|
||||
public void setConfirmTextSize(int confirmTextSize) {
|
||||
this.confirmTextSize = confirmTextSize;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return mTitle == null ? "" : mTitle;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
public String getTitleBackgroundColorStr() {
|
||||
return titleBackgroundColorStr == null ? "" : titleBackgroundColorStr;
|
||||
}
|
||||
|
||||
public void setTitleBackgroundColorStr(String titleBackgroundColorStr) {
|
||||
this.titleBackgroundColorStr = titleBackgroundColorStr;
|
||||
}
|
||||
|
||||
public String getTitleTextColorStr() {
|
||||
return titleTextColorStr == null ? "" : titleTextColorStr;
|
||||
}
|
||||
|
||||
public void setTitleTextColorStr(String titleTextColorStr) {
|
||||
this.titleTextColorStr = titleTextColorStr;
|
||||
}
|
||||
|
||||
public int getTitleTextSize() {
|
||||
return titleTextSize;
|
||||
}
|
||||
|
||||
public void setTitleTextSize(int titleTextSize) {
|
||||
this.titleTextSize = titleTextSize;
|
||||
}
|
||||
|
||||
public String getDefaultProvinceName() {
|
||||
return defaultProvinceName == null ? "" : defaultProvinceName;
|
||||
}
|
||||
|
||||
public void setDefaultProvinceName(String defaultProvinceName) {
|
||||
this.defaultProvinceName = defaultProvinceName;
|
||||
}
|
||||
|
||||
public String getDefaultCityName() {
|
||||
return defaultCityName == null ? "" : defaultCityName;
|
||||
}
|
||||
|
||||
public void setDefaultCityName(String defaultCityName) {
|
||||
this.defaultCityName = defaultCityName;
|
||||
}
|
||||
|
||||
public String getDefaultDistrict() {
|
||||
return defaultDistrict == null ? "" : defaultDistrict;
|
||||
}
|
||||
|
||||
public void setDefaultDistrict(String defaultDistrict) {
|
||||
this.defaultDistrict = defaultDistrict;
|
||||
}
|
||||
|
||||
public int setLanguage() {
|
||||
return loclanguage;
|
||||
}
|
||||
|
||||
public void getLanguage(int loclanguage) {
|
||||
this.loclanguage = loclanguage;
|
||||
}
|
||||
|
||||
public Integer getCustomItemLayout() {
|
||||
return customItemLayout == null ? NONE : customItemLayout;
|
||||
}
|
||||
|
||||
public void setCustomItemLayout(int customItemLayout) {
|
||||
this.customItemLayout = customItemLayout;
|
||||
}
|
||||
|
||||
public Integer getCustomItemTextViewId() {
|
||||
return customItemTextViewId == null ? NONE : customItemTextViewId;
|
||||
}
|
||||
|
||||
public void setCustomItemTextViewId(Integer customItemTextViewId) {
|
||||
this.customItemTextViewId = customItemTextViewId;
|
||||
}
|
||||
|
||||
public void setShowBackground(boolean showBackground) {
|
||||
isShowBackground = showBackground;
|
||||
}
|
||||
|
||||
public CityConfig(Builder builder) {
|
||||
|
||||
// this.mContext = builder.mContext;
|
||||
|
||||
/**
|
||||
* 标题栏相关的属性:
|
||||
* 0、标题栏背景颜色
|
||||
* 1、标题文字、大小、颜色
|
||||
*
|
||||
* 2、取消字体的颜色、大小、内容
|
||||
* 3、确认字体的颜色、大小、内容
|
||||
*/
|
||||
this.titleBackgroundColorStr = builder.titleBackgroundColorStr;
|
||||
|
||||
this.mTitle = builder.mTitle;
|
||||
this.titleTextColorStr = builder.titleTextColorStr;
|
||||
this.titleTextSize = builder.titleTextSize;
|
||||
|
||||
this.cancelTextColorStr = builder.cancelTextColorStr;
|
||||
this.cancelText = builder.cancelText;
|
||||
this.cancelTextSize = builder.cancelTextSize;
|
||||
|
||||
this.confirmTextColorStr = builder.confirmTextColorStr;
|
||||
this.confirmText = builder.confirmText;
|
||||
this.confirmTextSize = builder.confirmTextSize;
|
||||
|
||||
/**
|
||||
* 滚轮相关的属性:
|
||||
* 1、item显示的个数
|
||||
* 2、省份是否可以循环
|
||||
* 3、城市是否可以循环
|
||||
* 4、地区是否可以循环
|
||||
*/
|
||||
this.visibleItems = builder.visibleItems;
|
||||
this.isProvinceCyclic = builder.isProvinceCyclic;
|
||||
this.isDistrictCyclic = builder.isDistrictCyclic;
|
||||
this.isCityCyclic = builder.isCityCyclic;
|
||||
|
||||
this.loclanguage = builder.lauguage;
|
||||
|
||||
/**
|
||||
* 默认的省市区地址
|
||||
*/
|
||||
this.defaultDistrict = builder.defaultDistrict;
|
||||
this.defaultCityName = builder.defaultCityName;
|
||||
this.defaultProvinceName = builder.defaultProvinceName;
|
||||
|
||||
/**
|
||||
* 是否显示城市和地区
|
||||
*/
|
||||
this.mWheelType = builder.mWheelType;
|
||||
|
||||
/**
|
||||
* 是否显示半透明
|
||||
*/
|
||||
this.isShowBackground = builder.isShowBackground;
|
||||
|
||||
/**
|
||||
* 自定义item的布局,必须制定Layout和id
|
||||
*/
|
||||
this.customItemLayout = builder.customItemLayout;
|
||||
this.customItemTextViewId = builder.customItemTextViewId;
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*/
|
||||
this.drawShadows = builder.drawShadows;
|
||||
this.lineColor = builder.lineColor;
|
||||
this.lineHeigh = builder.lineHeigh;
|
||||
this.showGAT = builder.showGAT;
|
||||
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*/
|
||||
private int visibleItems = 5;
|
||||
|
||||
/**
|
||||
* 省滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isProvinceCyclic = true;
|
||||
|
||||
/**
|
||||
* 市滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isCityCyclic = true;
|
||||
|
||||
/**
|
||||
* 区滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isDistrictCyclic = true;
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelTextColorStr = "#000000";
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelText = "取消";
|
||||
|
||||
private int cancelTextSize = 16;
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmTextColorStr = "#0000FF";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmText = "确定";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private int confirmTextSize = 16;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String mTitle = "选择地区";
|
||||
|
||||
/**
|
||||
* 标题背景颜色
|
||||
*/
|
||||
private String titleBackgroundColorStr = "#E9E9E9";
|
||||
|
||||
/**
|
||||
* 标题颜色
|
||||
*/
|
||||
private String titleTextColorStr = "#585858";
|
||||
|
||||
/**
|
||||
* 标题字体大小
|
||||
*/
|
||||
private int titleTextSize = 18;
|
||||
|
||||
/**
|
||||
* 第一次默认的显示省份,一般配合定位,使用
|
||||
*/
|
||||
private String defaultProvinceName = "浙江";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示城市,一般配合定位,使用
|
||||
*/
|
||||
private String defaultCityName = "杭州";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示,一般配合定位,使用
|
||||
*/
|
||||
private String defaultDistrict = "滨江区";
|
||||
|
||||
private int lauguage = 0;
|
||||
|
||||
|
||||
/**
|
||||
* 定义默认显示省市区三级联动的滚轮选择器
|
||||
*/
|
||||
private CityConfig.WheelType mWheelType = CityConfig.WheelType.PRO_CITY_DIS;
|
||||
|
||||
/**
|
||||
* 是否显示半透明的背景
|
||||
*/
|
||||
private boolean isShowBackground = true;
|
||||
|
||||
/**
|
||||
* 自定义的item布局
|
||||
*/
|
||||
private Integer customItemLayout;
|
||||
|
||||
/**
|
||||
* 自定义的item txt id
|
||||
*/
|
||||
private Integer customItemTextViewId;
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*/
|
||||
private boolean drawShadows = true;
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
*/
|
||||
private String lineColor = "#C7C7C7";
|
||||
|
||||
/**
|
||||
* 是否显示港澳台城市数据
|
||||
*/
|
||||
private boolean showGAT = false;
|
||||
|
||||
/**
|
||||
* 中间线的宽度
|
||||
*/
|
||||
private int lineHeigh = 3;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示港澳台城市数据,默认不显示
|
||||
* @param showGAT
|
||||
* @return
|
||||
*/
|
||||
public Builder setShowGAT(boolean showGAT) {
|
||||
this.showGAT = showGAT;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 中间线的宽度
|
||||
* @param lineHeigh
|
||||
* @return
|
||||
*/
|
||||
public Builder setLineHeigh(int lineHeigh) {
|
||||
this.lineHeigh = lineHeigh;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
* @param lineColor
|
||||
* @return
|
||||
*/
|
||||
public Builder setLineColor(String lineColor) {
|
||||
this.lineColor = lineColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*
|
||||
* @param drawShadows
|
||||
* @return
|
||||
*/
|
||||
public Builder drawShadows(boolean drawShadows) {
|
||||
this.drawShadows = drawShadows;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题背景颜色
|
||||
*
|
||||
* @param colorBg
|
||||
* @return
|
||||
*/
|
||||
public Builder titleBackgroundColor(String colorBg) {
|
||||
this.titleBackgroundColorStr = colorBg;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题字体颜色
|
||||
*
|
||||
* @param titleTextColorStr
|
||||
* @return
|
||||
*/
|
||||
public Builder titleTextColor(String titleTextColorStr) {
|
||||
this.titleTextColorStr = titleTextColorStr;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题字体大小
|
||||
*
|
||||
* @param titleTextSize
|
||||
* @return
|
||||
*/
|
||||
public Builder titleTextSize(int titleTextSize) {
|
||||
this.titleTextSize = titleTextSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
*
|
||||
* @param mtitle
|
||||
* @return
|
||||
*/
|
||||
public Builder title(String mtitle) {
|
||||
this.mTitle = mtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认按钮文字
|
||||
*
|
||||
* @param confirmTextSize
|
||||
* @return
|
||||
*/
|
||||
public Builder confirmTextSize(int confirmTextSize) {
|
||||
this.confirmTextSize = confirmTextSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认按钮文字
|
||||
*
|
||||
* @param confirmText
|
||||
* @return
|
||||
*/
|
||||
public Builder confirmText(String confirmText) {
|
||||
this.confirmText = confirmText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认按钮文字颜色
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public Builder confirTextColor(String color) {
|
||||
this.confirmTextColorStr = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮文字颜色
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public Builder cancelTextColor(String color) {
|
||||
this.cancelTextColorStr = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮文字大小
|
||||
*
|
||||
* @param cancelTextSize
|
||||
* @return
|
||||
*/
|
||||
public Builder cancelTextSize(int cancelTextSize) {
|
||||
this.cancelTextSize = cancelTextSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮文字
|
||||
*
|
||||
* @param cancelText
|
||||
* @return
|
||||
*/
|
||||
public Builder cancelText(String cancelText) {
|
||||
this.cancelText = cancelText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*
|
||||
* @param visibleItems
|
||||
* @return
|
||||
*/
|
||||
public Builder visibleItemsCount(int visibleItems) {
|
||||
this.visibleItems = visibleItems;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 省滚轮是否循环滚动
|
||||
*
|
||||
* @param isProvinceCyclic
|
||||
* @return
|
||||
*/
|
||||
public Builder provinceCyclic(boolean isProvinceCyclic) {
|
||||
this.isProvinceCyclic = isProvinceCyclic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 市滚轮是否循环滚动
|
||||
*
|
||||
* @param isCityCyclic
|
||||
* @return
|
||||
*/
|
||||
public Builder cityCyclic(boolean isCityCyclic) {
|
||||
this.isCityCyclic = isCityCyclic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 区滚轮是否循环滚动
|
||||
*
|
||||
* @param isDistrictCyclic
|
||||
* @return
|
||||
*/
|
||||
public Builder districtCyclic(boolean isDistrictCyclic) {
|
||||
this.isDistrictCyclic = isDistrictCyclic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示省市区三级联动的显示状态
|
||||
* PRO:只显示省份的一级选择器
|
||||
* PRO_CITY:显示省份和城市二级联动的选择器
|
||||
* PRO_CITY_DIS:显示省份和城市和县区三级联动的选择器
|
||||
* @param wheelType
|
||||
* @return
|
||||
*/
|
||||
public Builder setCityWheelType(CityConfig.WheelType wheelType) {
|
||||
this.mWheelType = wheelType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认的显示省份,一般配合定位,使用
|
||||
*
|
||||
* @param defaultProvinceName
|
||||
* @return
|
||||
*/
|
||||
public Builder province(String defaultProvinceName) {
|
||||
this.defaultProvinceName = defaultProvinceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认得显示城市,一般配合定位,使用
|
||||
*
|
||||
* @param defaultCityName
|
||||
* @return
|
||||
*/
|
||||
public Builder city(String defaultCityName) {
|
||||
this.defaultCityName = defaultCityName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认地区显示,一般配合定位,使用
|
||||
*
|
||||
* @param defaultDistrict
|
||||
* @return
|
||||
*/
|
||||
public Builder district(String defaultDistrict) {
|
||||
this.defaultDistrict = defaultDistrict;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认地区显示,一般配合定位,使用
|
||||
*
|
||||
* @param defaultDistrict
|
||||
* @return
|
||||
*/
|
||||
public Builder setLanguage(int language) {
|
||||
this.lauguage = language;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示半透明的背景
|
||||
* @param isShowBackground
|
||||
* @return
|
||||
*/
|
||||
public Builder showBackground(boolean isShowBackground) {
|
||||
this.isShowBackground = isShowBackground;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义item布局
|
||||
* @param itemLayout
|
||||
* @return
|
||||
*/
|
||||
public Builder setCustomItemLayout(Integer itemLayout) {
|
||||
this.customItemLayout = itemLayout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义item布局中的id
|
||||
* @param setCustomItemTextViewId
|
||||
* @return
|
||||
*/
|
||||
public Builder setCustomItemTextViewId(Integer setCustomItemTextViewId) {
|
||||
this.customItemTextViewId = setCustomItemTextViewId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CityConfig build() {
|
||||
CityConfig config = new CityConfig(this);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
package com.lljjcoder.citywheel;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.lljjcoder.Constant;
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
import com.lljjcoder.utils.utils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 省市区解析辅助类
|
||||
* 作者:liji on 2017/11/4 10:09
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityParseHelper {
|
||||
|
||||
/**
|
||||
* 省份数据
|
||||
*/
|
||||
private ArrayList<ProvinceBean> mProvinceBeanArrayList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 城市数据
|
||||
*/
|
||||
private ArrayList<ArrayList<CityBean>> mCityBeanArrayList;
|
||||
|
||||
/**
|
||||
* 地区数据
|
||||
*/
|
||||
private ArrayList<ArrayList<ArrayList<DistrictBean>>> mDistrictBeanArrayList;
|
||||
|
||||
private List<ProvinceBean> mProvinceBeenArray;
|
||||
|
||||
private ProvinceBean mProvinceBean;
|
||||
|
||||
private CityBean mCityBean;
|
||||
|
||||
private DistrictBean mDistrictBean;
|
||||
|
||||
// private CityConfig config;
|
||||
|
||||
/**
|
||||
* key - 省 value - 市
|
||||
*/
|
||||
private Map<String, List<CityBean>> mPro_CityMap = new HashMap<String, List<CityBean>>();
|
||||
|
||||
/**
|
||||
* key - 市 values - 区
|
||||
*/
|
||||
private Map<String, List<DistrictBean>> mCity_DisMap = new HashMap<String, List<DistrictBean>>();
|
||||
|
||||
/**
|
||||
* key - 区 values - 邮编
|
||||
*/
|
||||
private Map<String, DistrictBean> mDisMap = new HashMap<String, DistrictBean>();
|
||||
|
||||
public ArrayList<ProvinceBean> getProvinceBeanArrayList() {
|
||||
return mProvinceBeanArrayList;
|
||||
}
|
||||
|
||||
public void setProvinceBeanArrayList(ArrayList<ProvinceBean> provinceBeanArrayList) {
|
||||
mProvinceBeanArrayList = provinceBeanArrayList;
|
||||
}
|
||||
|
||||
public ArrayList<ArrayList<CityBean>> getCityBeanArrayList() {
|
||||
return mCityBeanArrayList;
|
||||
}
|
||||
|
||||
public void setCityBeanArrayList(ArrayList<ArrayList<CityBean>> cityBeanArrayList) {
|
||||
mCityBeanArrayList = cityBeanArrayList;
|
||||
}
|
||||
|
||||
public ArrayList<ArrayList<ArrayList<DistrictBean>>> getDistrictBeanArrayList() {
|
||||
return mDistrictBeanArrayList;
|
||||
}
|
||||
|
||||
public void setDistrictBeanArrayList(ArrayList<ArrayList<ArrayList<DistrictBean>>> districtBeanArrayList) {
|
||||
mDistrictBeanArrayList = districtBeanArrayList;
|
||||
}
|
||||
|
||||
public List<ProvinceBean> getProvinceBeenArray() {
|
||||
return mProvinceBeenArray;
|
||||
}
|
||||
|
||||
public void setProvinceBeenArray(List<ProvinceBean> provinceBeenArray) {
|
||||
mProvinceBeenArray = provinceBeenArray;
|
||||
}
|
||||
|
||||
public ProvinceBean getProvinceBean() {
|
||||
return mProvinceBean;
|
||||
}
|
||||
|
||||
public void setProvinceBean(ProvinceBean provinceBean) {
|
||||
mProvinceBean = provinceBean;
|
||||
}
|
||||
|
||||
public CityBean getCityBean() {
|
||||
return mCityBean;
|
||||
}
|
||||
|
||||
public void setCityBean(CityBean cityBean) {
|
||||
mCityBean = cityBean;
|
||||
}
|
||||
|
||||
public DistrictBean getDistrictBean() {
|
||||
return mDistrictBean;
|
||||
}
|
||||
|
||||
public void setDistrictBean(DistrictBean districtBean) {
|
||||
mDistrictBean = districtBean;
|
||||
}
|
||||
|
||||
public Map<String, List<CityBean>> getPro_CityMap() {
|
||||
return mPro_CityMap;
|
||||
}
|
||||
|
||||
public void setPro_CityMap(Map<String, List<CityBean>> pro_CityMap) {
|
||||
mPro_CityMap = pro_CityMap;
|
||||
}
|
||||
|
||||
public Map<String, List<DistrictBean>> getCity_DisMap() {
|
||||
return mCity_DisMap;
|
||||
}
|
||||
|
||||
public void setCity_DisMap(Map<String, List<DistrictBean>> city_DisMap) {
|
||||
mCity_DisMap = city_DisMap;
|
||||
}
|
||||
|
||||
public Map<String, DistrictBean> getDisMap() {
|
||||
return mDisMap;
|
||||
}
|
||||
|
||||
public void setDisMap(Map<String, DistrictBean> disMap) {
|
||||
mDisMap = disMap;
|
||||
}
|
||||
|
||||
public CityParseHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据,解析json数据
|
||||
*/
|
||||
public void initData(Context context) {
|
||||
|
||||
String cityJson = utils.getJson(context, Constant.CITY_DATA);
|
||||
Type type = new TypeToken<ArrayList<ProvinceBean>>() {
|
||||
}.getType();
|
||||
|
||||
mProvinceBeanArrayList = new Gson().fromJson(cityJson, type);
|
||||
|
||||
if (mProvinceBeanArrayList == null || mProvinceBeanArrayList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCityBeanArrayList = new ArrayList<>(mProvinceBeanArrayList.size());
|
||||
mDistrictBeanArrayList = new ArrayList<>(mProvinceBeanArrayList.size());
|
||||
|
||||
//*/ 初始化默认选中的省、市、区,默认选中第一个省份的第一个市区中的第一个区县
|
||||
if (mProvinceBeanArrayList != null && !mProvinceBeanArrayList.isEmpty()) {
|
||||
mProvinceBean = mProvinceBeanArrayList.get(0);
|
||||
List<CityBean> cityList = mProvinceBean.getCityList();
|
||||
if (cityList != null && !cityList.isEmpty() && cityList.size() > 0) {
|
||||
mCityBean = cityList.get(0);
|
||||
List<DistrictBean> districtList = mCityBean.getCityList();
|
||||
if (districtList != null && !districtList.isEmpty() && districtList.size() > 0) {
|
||||
mDistrictBean = districtList.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//省份数据
|
||||
mProvinceBeenArray = new ArrayList<ProvinceBean>();
|
||||
|
||||
for (int p = 0; p < mProvinceBeanArrayList.size(); p++) {
|
||||
|
||||
//遍历每个省份
|
||||
ProvinceBean itemProvince = mProvinceBeanArrayList.get(p);
|
||||
|
||||
//每个省份对应下面的市
|
||||
ArrayList<CityBean> cityList = itemProvince.getCityList();
|
||||
|
||||
//当前省份下面的所有城市
|
||||
|
||||
// List<CityBean> cityNames = new ArrayList<>();
|
||||
|
||||
//遍历当前省份下面城市的所有数据
|
||||
for (int j = 0; j < cityList.size(); j++) {
|
||||
// cityNames[j] = cityList.get(j);
|
||||
|
||||
//当前省份下面每个城市下面再次对应的区或者县
|
||||
List<DistrictBean> districtList = cityList.get(j).getCityList();
|
||||
if (districtList == null) {
|
||||
break;
|
||||
}
|
||||
// DistrictBean[] distrinctArray = new DistrictBean[districtList.size()];
|
||||
|
||||
for (int k = 0; k < districtList.size(); k++) {
|
||||
|
||||
// 遍历市下面所有区/县的数据
|
||||
DistrictBean districtModel = districtList.get(k);
|
||||
|
||||
//存放 省市区-区 数据
|
||||
mDisMap.put(itemProvince.getName() + cityList.get(j).getName() + districtList.get(k).getName(),
|
||||
districtModel);
|
||||
|
||||
// districtList.add(districtModel);
|
||||
|
||||
}
|
||||
// 市-区/县的数据,保存到mDistrictDatasMap
|
||||
mCity_DisMap.put(itemProvince.getName() + cityList.get(j).getName(), districtList);
|
||||
|
||||
}
|
||||
|
||||
// 省-市的数据,保存到mCitisDatasMap
|
||||
mPro_CityMap.put(itemProvince.getName(), cityList);
|
||||
|
||||
mCityBeanArrayList.add(cityList);
|
||||
|
||||
//只有显示三级联动,才会执行
|
||||
ArrayList<ArrayList<DistrictBean>> array2DistrictLists = new ArrayList<>(cityList.size());
|
||||
|
||||
for (int c = 0; c < cityList.size(); c++) {
|
||||
CityBean cityBean = cityList.get(c);
|
||||
array2DistrictLists.add(cityBean.getCityList());
|
||||
}
|
||||
mDistrictBeanArrayList.add(array2DistrictLists);
|
||||
|
||||
// }
|
||||
mProvinceBeenArray.add(p, itemProvince);
|
||||
//赋值所有省份的名称
|
||||
// mProvinceBeenArray[p] = ;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化数据,解析json数据
|
||||
*/
|
||||
public void initDataTw(Context context) {
|
||||
|
||||
String cityJson = utils.getJson(context, Constant.CITY_DATA_TW);
|
||||
Type type = new TypeToken<ArrayList<ProvinceBean>>() {
|
||||
}.getType();
|
||||
|
||||
mProvinceBeanArrayList = new Gson().fromJson(cityJson, type);
|
||||
|
||||
if (mProvinceBeanArrayList == null || mProvinceBeanArrayList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCityBeanArrayList = new ArrayList<>(mProvinceBeanArrayList.size());
|
||||
mDistrictBeanArrayList = new ArrayList<>(mProvinceBeanArrayList.size());
|
||||
|
||||
//*/ 初始化默认选中的省、市、区,默认选中第一个省份的第一个市区中的第一个区县
|
||||
if (mProvinceBeanArrayList != null && !mProvinceBeanArrayList.isEmpty()) {
|
||||
mProvinceBean = mProvinceBeanArrayList.get(0);
|
||||
List<CityBean> cityList = mProvinceBean.getCityList();
|
||||
if (cityList != null && !cityList.isEmpty() && cityList.size() > 0) {
|
||||
mCityBean = cityList.get(0);
|
||||
List<DistrictBean> districtList = mCityBean.getCityList();
|
||||
if (districtList != null && !districtList.isEmpty() && districtList.size() > 0) {
|
||||
mDistrictBean = districtList.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//省份数据
|
||||
mProvinceBeenArray = new ArrayList<ProvinceBean>();
|
||||
|
||||
for (int p = 0; p < mProvinceBeanArrayList.size(); p++) {
|
||||
|
||||
//遍历每个省份
|
||||
ProvinceBean itemProvince = mProvinceBeanArrayList.get(p);
|
||||
|
||||
//每个省份对应下面的市
|
||||
ArrayList<CityBean> cityList = itemProvince.getCityList();
|
||||
|
||||
//当前省份下面的所有城市
|
||||
|
||||
// List<CityBean> cityNames = new ArrayList<>();
|
||||
|
||||
//遍历当前省份下面城市的所有数据
|
||||
for (int j = 0; j < cityList.size(); j++) {
|
||||
// cityNames[j] = cityList.get(j);
|
||||
|
||||
//当前省份下面每个城市下面再次对应的区或者县
|
||||
List<DistrictBean> districtList = cityList.get(j).getCityList();
|
||||
if (districtList == null) {
|
||||
break;
|
||||
}
|
||||
// DistrictBean[] distrinctArray = new DistrictBean[districtList.size()];
|
||||
|
||||
for (int k = 0; k < districtList.size(); k++) {
|
||||
|
||||
// 遍历市下面所有区/县的数据
|
||||
DistrictBean districtModel = districtList.get(k);
|
||||
|
||||
//存放 省市区-区 数据
|
||||
mDisMap.put(itemProvince.getName() + cityList.get(j).getName() + districtList.get(k).getName(),
|
||||
districtModel);
|
||||
|
||||
// districtList.add(districtModel);
|
||||
|
||||
}
|
||||
// 市-区/县的数据,保存到mDistrictDatasMap
|
||||
mCity_DisMap.put(itemProvince.getName() + cityList.get(j).getName(), districtList);
|
||||
|
||||
}
|
||||
|
||||
// 省-市的数据,保存到mCitisDatasMap
|
||||
mPro_CityMap.put(itemProvince.getName(), cityList);
|
||||
|
||||
mCityBeanArrayList.add(cityList);
|
||||
|
||||
//只有显示三级联动,才会执行
|
||||
ArrayList<ArrayList<DistrictBean>> array2DistrictLists = new ArrayList<>(cityList.size());
|
||||
|
||||
for (int c = 0; c < cityList.size(); c++) {
|
||||
CityBean cityBean = cityList.get(c);
|
||||
array2DistrictLists.add(cityBean.getCityList());
|
||||
}
|
||||
mDistrictBeanArrayList.add(array2DistrictLists);
|
||||
|
||||
// }
|
||||
mProvinceBeenArray.add(p, itemProvince);
|
||||
//赋值所有省份的名称
|
||||
// mProvinceBeenArray[p] = ;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,827 @@
|
||||
package com.lljjcoder.citywheel;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.lljjcoder.bean.CustomCityData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 城市选择器样式配置
|
||||
* 作者:liji on 2017/11/4 10:31
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CustomConfig {
|
||||
|
||||
public static final Integer NONE = -1111;
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*/
|
||||
private int visibleItems = 5;
|
||||
|
||||
/**
|
||||
* 省滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isProvinceCyclic = true;
|
||||
|
||||
/**
|
||||
* 市滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isCityCyclic = true;
|
||||
|
||||
/**
|
||||
* 区滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isDistrictCyclic = true;
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelTextColorStr = "#000000";
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelText = "取消";
|
||||
|
||||
private int cancelTextSize = 16;
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmTextColorStr = "#0000FF";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmText = "确定";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private int confirmTextSize = 16;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String mTitle = "选择地区";
|
||||
|
||||
/**
|
||||
* 标题背景颜色
|
||||
*/
|
||||
private String titleBackgroundColorStr = "#E9E9E9";
|
||||
|
||||
/**
|
||||
* 标题颜色
|
||||
*/
|
||||
private String titleTextColorStr = "#585858";
|
||||
|
||||
/**
|
||||
* 标题字体大小
|
||||
*/
|
||||
private int titleTextSize = 18;
|
||||
|
||||
|
||||
/**
|
||||
* 自定义的item布局
|
||||
*/
|
||||
private Integer customItemLayout;
|
||||
|
||||
/**
|
||||
* 自定义的item txt id
|
||||
*/
|
||||
private Integer customItemTextViewId;
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*/
|
||||
private boolean drawShadows = true;
|
||||
|
||||
|
||||
/**
|
||||
* 第一次默认的显示省份,一般配合定位,使用
|
||||
*/
|
||||
private String defaultProvinceName = "";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示城市,一般配合定位,使用
|
||||
*/
|
||||
private String defaultCityName = "";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示,一般配合定位,使用
|
||||
*/
|
||||
private String defaultDistrict = "";
|
||||
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
*/
|
||||
private String lineColor = "#C7C7C7";
|
||||
|
||||
/**
|
||||
* 中间线的宽度
|
||||
*/
|
||||
private int lineHeigh = 3;
|
||||
|
||||
/**
|
||||
* 默认显示的城市数据,只包含省市区名称
|
||||
*/
|
||||
/**
|
||||
* 定义显示省市区三种滚轮的显示状态
|
||||
* PRO:只显示省份的一级选择器
|
||||
* PRO_CITY:显示省份和城市二级联动的选择器
|
||||
* PRO_CITY_DIS:显示省份和城市和县区三级联动的选择器
|
||||
*/
|
||||
public enum WheelType {
|
||||
PRO, PRO_CITY, PRO_CITY_DIS
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义默认显示省市区三级联动的滚轮选择器
|
||||
*/
|
||||
public CustomConfig.WheelType mWheelType = CustomConfig.WheelType.PRO_CITY_DIS;
|
||||
|
||||
public CustomConfig.WheelType getWheelType() {
|
||||
return mWheelType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否显示半透明的背景
|
||||
*/
|
||||
private boolean isShowBackground = true;
|
||||
|
||||
private List<CustomCityData> cityDataList = new ArrayList<>();
|
||||
|
||||
public boolean isShowBackground() {
|
||||
return isShowBackground;
|
||||
}
|
||||
|
||||
public String getLineColor() {
|
||||
return lineColor == null ? "" : lineColor;
|
||||
}
|
||||
|
||||
public void setLineColor(String lineColor) {
|
||||
this.lineColor = lineColor;
|
||||
}
|
||||
|
||||
public int getLineHeigh() {
|
||||
return lineHeigh;
|
||||
}
|
||||
|
||||
public void setLineHeigh(int lineHeigh) {
|
||||
this.lineHeigh = lineHeigh;
|
||||
}
|
||||
|
||||
public boolean isDrawShadows() {
|
||||
return drawShadows;
|
||||
}
|
||||
|
||||
public void setDrawShadows(boolean drawShadows) {
|
||||
this.drawShadows = drawShadows;
|
||||
}
|
||||
|
||||
public int getVisibleItems() {
|
||||
return visibleItems;
|
||||
}
|
||||
|
||||
public void setVisibleItems(int visibleItems) {
|
||||
this.visibleItems = visibleItems;
|
||||
}
|
||||
|
||||
public boolean isProvinceCyclic() {
|
||||
return isProvinceCyclic;
|
||||
}
|
||||
|
||||
public void setProvinceCyclic(boolean provinceCyclic) {
|
||||
isProvinceCyclic = provinceCyclic;
|
||||
}
|
||||
|
||||
public boolean isCityCyclic() {
|
||||
return isCityCyclic;
|
||||
}
|
||||
|
||||
public void setCityCyclic(boolean cityCyclic) {
|
||||
isCityCyclic = cityCyclic;
|
||||
}
|
||||
|
||||
public boolean isDistrictCyclic() {
|
||||
return isDistrictCyclic;
|
||||
}
|
||||
|
||||
public void setDistrictCyclic(boolean districtCyclic) {
|
||||
isDistrictCyclic = districtCyclic;
|
||||
}
|
||||
|
||||
public String getDefaultProvinceName() {
|
||||
return defaultProvinceName == null ? "" : defaultProvinceName;
|
||||
}
|
||||
|
||||
public void setDefaultProvinceName(String defaultProvinceName) {
|
||||
this.defaultProvinceName = defaultProvinceName;
|
||||
}
|
||||
|
||||
public String getDefaultCityName() {
|
||||
return defaultCityName == null ? "" : defaultCityName;
|
||||
}
|
||||
|
||||
public void setDefaultCityName(String defaultCityName) {
|
||||
this.defaultCityName = defaultCityName;
|
||||
}
|
||||
|
||||
public String getDefaultDistrict() {
|
||||
return defaultDistrict == null ? "" : defaultDistrict;
|
||||
}
|
||||
|
||||
public void setDefaultDistrict(String defaultDistrict) {
|
||||
this.defaultDistrict = defaultDistrict;
|
||||
}
|
||||
public String getCancelTextColorStr() {
|
||||
return cancelTextColorStr == null ? "" : cancelTextColorStr;
|
||||
}
|
||||
|
||||
public void setCancelTextColorStr(String cancelTextColorStr) {
|
||||
this.cancelTextColorStr = cancelTextColorStr;
|
||||
}
|
||||
|
||||
public String getCancelText() {
|
||||
return cancelText == null ? "" : cancelText;
|
||||
}
|
||||
|
||||
public void setCancelText(String cancelText) {
|
||||
this.cancelText = cancelText;
|
||||
}
|
||||
|
||||
public int getCancelTextSize() {
|
||||
return cancelTextSize;
|
||||
}
|
||||
|
||||
public void setCancelTextSize(int cancelTextSize) {
|
||||
this.cancelTextSize = cancelTextSize;
|
||||
}
|
||||
|
||||
public String getConfirmTextColorStr() {
|
||||
return confirmTextColorStr == null ? "" : confirmTextColorStr;
|
||||
}
|
||||
|
||||
public void setConfirmTextColorStr(String confirmTextColorStr) {
|
||||
this.confirmTextColorStr = confirmTextColorStr;
|
||||
}
|
||||
|
||||
public String getConfirmText() {
|
||||
return confirmText == null ? "" : confirmText;
|
||||
}
|
||||
|
||||
public void setConfirmText(String confirmText) {
|
||||
this.confirmText = confirmText;
|
||||
}
|
||||
|
||||
public int getConfirmTextSize() {
|
||||
return confirmTextSize;
|
||||
}
|
||||
|
||||
public void setConfirmTextSize(int confirmTextSize) {
|
||||
this.confirmTextSize = confirmTextSize;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return mTitle == null ? "" : mTitle;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
public String getTitleBackgroundColorStr() {
|
||||
return titleBackgroundColorStr == null ? "" : titleBackgroundColorStr;
|
||||
}
|
||||
|
||||
public void setTitleBackgroundColorStr(String titleBackgroundColorStr) {
|
||||
this.titleBackgroundColorStr = titleBackgroundColorStr;
|
||||
}
|
||||
|
||||
public String getTitleTextColorStr() {
|
||||
return titleTextColorStr == null ? "" : titleTextColorStr;
|
||||
}
|
||||
|
||||
public void setTitleTextColorStr(String titleTextColorStr) {
|
||||
this.titleTextColorStr = titleTextColorStr;
|
||||
}
|
||||
|
||||
public int getTitleTextSize() {
|
||||
return titleTextSize;
|
||||
}
|
||||
|
||||
public void setTitleTextSize(int titleTextSize) {
|
||||
this.titleTextSize = titleTextSize;
|
||||
}
|
||||
|
||||
//
|
||||
public Integer getCustomItemLayout() {
|
||||
return customItemLayout == null ? NONE : customItemLayout;
|
||||
}
|
||||
|
||||
public void setCustomItemLayout(int customItemLayout) {
|
||||
this.customItemLayout = customItemLayout;
|
||||
}
|
||||
|
||||
public Integer getCustomItemTextViewId() {
|
||||
return customItemTextViewId == null ? NONE : customItemTextViewId;
|
||||
}
|
||||
|
||||
public void setCustomItemTextViewId(Integer customItemTextViewId) {
|
||||
this.customItemTextViewId = customItemTextViewId;
|
||||
}
|
||||
|
||||
public List<CustomCityData> getCityDataList() {
|
||||
return cityDataList;
|
||||
}
|
||||
|
||||
public void setCityDataList(List<CustomCityData> cityDataList) {
|
||||
this.cityDataList = cityDataList;
|
||||
}
|
||||
|
||||
public void setShowBackground(boolean showBackground) {
|
||||
isShowBackground = showBackground;
|
||||
}
|
||||
|
||||
public CustomConfig(Builder builder) {
|
||||
|
||||
|
||||
/**
|
||||
* 标题栏相关的属性:
|
||||
* 0、标题栏背景颜色
|
||||
* 1、标题文字、大小、颜色
|
||||
*
|
||||
* 2、取消字体的颜色、大小、内容
|
||||
* 3、确认字体的颜色、大小、内容
|
||||
*/
|
||||
this.titleBackgroundColorStr = builder.titleBackgroundColorStr;
|
||||
|
||||
this.mTitle = builder.mTitle;
|
||||
this.titleTextColorStr = builder.titleTextColorStr;
|
||||
this.titleTextSize = builder.titleTextSize;
|
||||
|
||||
this.cancelTextColorStr = builder.cancelTextColorStr;
|
||||
this.cancelText = builder.cancelText;
|
||||
this.cancelTextSize = builder.cancelTextSize;
|
||||
|
||||
this.confirmTextColorStr = builder.confirmTextColorStr;
|
||||
this.confirmText = builder.confirmText;
|
||||
this.confirmTextSize = builder.confirmTextSize;
|
||||
|
||||
/**
|
||||
* 滚轮相关的属性:
|
||||
* 1、item显示的个数
|
||||
* 2、省份是否可以循环
|
||||
* 3、城市是否可以循环
|
||||
* 4、地区是否可以循环
|
||||
*/
|
||||
this.visibleItems = builder.visibleItems;
|
||||
this.isProvinceCyclic = builder.isProvinceCyclic;
|
||||
this.isDistrictCyclic = builder.isDistrictCyclic;
|
||||
this.isCityCyclic = builder.isCityCyclic;
|
||||
/**
|
||||
* 默认的省市区地址
|
||||
*/
|
||||
this.defaultDistrict = builder.defaultDistrict;
|
||||
this.defaultCityName = builder.defaultCityName;
|
||||
this.defaultProvinceName = builder.defaultProvinceName;
|
||||
|
||||
|
||||
/**
|
||||
* 是否显示城市和地区
|
||||
*/
|
||||
this.mWheelType = builder.mWheelType;
|
||||
|
||||
|
||||
/**
|
||||
* 是否显示半透明
|
||||
*/
|
||||
this.isShowBackground = builder.isShowBackground;
|
||||
//
|
||||
/**
|
||||
* 自定义item的布局,必须制定Layout和id
|
||||
*/
|
||||
this.customItemLayout = builder.customItemLayout;
|
||||
this.customItemTextViewId = builder.customItemTextViewId;
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*/
|
||||
this.drawShadows = builder.drawShadows;
|
||||
this.lineColor = builder.lineColor;
|
||||
this.lineHeigh = builder.lineHeigh;
|
||||
this.cityDataList = builder.cityDataList;
|
||||
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*/
|
||||
private int visibleItems = 5;
|
||||
|
||||
/**
|
||||
* 省滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isProvinceCyclic = true;
|
||||
|
||||
/**
|
||||
* 市滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isCityCyclic = true;
|
||||
|
||||
/**
|
||||
* 区滚轮是否循环滚动
|
||||
*/
|
||||
private boolean isDistrictCyclic = true;
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelTextColorStr = "#000000";
|
||||
|
||||
/**
|
||||
* Color.BLACK
|
||||
*/
|
||||
private String cancelText = "取消";
|
||||
|
||||
private int cancelTextSize = 16;
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmTextColorStr = "#0000FF";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private String confirmText = "确定";
|
||||
|
||||
/**
|
||||
* Color.BLUE
|
||||
*/
|
||||
private int confirmTextSize = 16;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String mTitle = "选择地区";
|
||||
|
||||
/**
|
||||
* 标题背景颜色
|
||||
*/
|
||||
private String titleBackgroundColorStr = "#E9E9E9";
|
||||
|
||||
/**
|
||||
* 标题颜色
|
||||
*/
|
||||
private String titleTextColorStr = "#585858";
|
||||
|
||||
/**
|
||||
* 标题字体大小
|
||||
*/
|
||||
private int titleTextSize = 18;
|
||||
|
||||
|
||||
/**
|
||||
* 是否显示半透明的背景
|
||||
*/
|
||||
private boolean isShowBackground = true;
|
||||
|
||||
/**
|
||||
* 自定义的item布局
|
||||
*/
|
||||
private Integer customItemLayout;
|
||||
|
||||
/**
|
||||
* 自定义的item txt id
|
||||
*/
|
||||
private Integer customItemTextViewId;
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*/
|
||||
private boolean drawShadows = true;
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
*/
|
||||
private String lineColor = "#C7C7C7";
|
||||
/**
|
||||
* 定义默认显示省市区三级联动的滚轮选择器
|
||||
*/
|
||||
private CustomConfig.WheelType mWheelType = CustomConfig.WheelType.PRO_CITY_DIS;
|
||||
/**
|
||||
* 中间线的宽度
|
||||
*/
|
||||
private int lineHeigh = 3;
|
||||
|
||||
private List<CustomCityData> cityDataList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 第一次默认的显示省份,一般配合定位,使用
|
||||
*/
|
||||
private String defaultProvinceName = "";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示城市,一般配合定位,使用
|
||||
*/
|
||||
private String defaultCityName = "";
|
||||
|
||||
/**
|
||||
* 第一次默认得显示,一般配合定位,使用
|
||||
*/
|
||||
private String defaultDistrict = "";
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 显示省市区三级联动的显示状态
|
||||
* PRO:只显示省份的一级选择器
|
||||
* PRO_CITY:显示省份和城市二级联动的选择器
|
||||
* PRO_CITY_DIS:显示省份和城市和县区三级联动的选择器
|
||||
*
|
||||
* @param wheelType
|
||||
* @return
|
||||
*/
|
||||
public CustomConfig.Builder setCityWheelType(CustomConfig.WheelType wheelType) {
|
||||
this.mWheelType = wheelType;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder setCityData(List<CustomCityData> data) {
|
||||
this.cityDataList = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认的显示省份,一般配合定位,使用
|
||||
*
|
||||
* @param defaultProvinceName
|
||||
* @return
|
||||
*/
|
||||
public Builder province(String defaultProvinceName) {
|
||||
this.defaultProvinceName = defaultProvinceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认得显示城市,一般配合定位,使用
|
||||
*
|
||||
* @param defaultCityName
|
||||
* @return
|
||||
*/
|
||||
public Builder city(String defaultCityName) {
|
||||
this.defaultCityName = defaultCityName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次默认地区显示,一般配合定位,使用
|
||||
*
|
||||
* @param defaultDistrict
|
||||
* @return
|
||||
*/
|
||||
public Builder district(String defaultDistrict) {
|
||||
this.defaultDistrict = defaultDistrict;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 中间线的宽度
|
||||
*
|
||||
* @param lineHeigh
|
||||
* @return
|
||||
*/
|
||||
public Builder setLineHeigh(int lineHeigh) {
|
||||
this.lineHeigh = lineHeigh;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
*
|
||||
* @param lineColor
|
||||
* @return
|
||||
*/
|
||||
public Builder setLineColor(String lineColor) {
|
||||
this.lineColor = lineColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示滚轮上面的模糊阴影效果
|
||||
*
|
||||
* @param drawShadows
|
||||
* @return
|
||||
*/
|
||||
public Builder drawShadows(boolean drawShadows) {
|
||||
this.drawShadows = drawShadows;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题背景颜色
|
||||
*
|
||||
* @param colorBg
|
||||
* @return
|
||||
*/
|
||||
public Builder titleBackgroundColor(String colorBg) {
|
||||
this.titleBackgroundColorStr = colorBg;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题字体颜色
|
||||
*
|
||||
* @param titleTextColorStr
|
||||
* @return
|
||||
*/
|
||||
public Builder titleTextColor(String titleTextColorStr) {
|
||||
this.titleTextColorStr = titleTextColorStr;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题字体大小
|
||||
*
|
||||
* @param titleTextSize
|
||||
* @return
|
||||
*/
|
||||
public Builder titleTextSize(int titleTextSize) {
|
||||
this.titleTextSize = titleTextSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题
|
||||
*
|
||||
* @param mtitle
|
||||
* @return
|
||||
*/
|
||||
public Builder title(String mtitle) {
|
||||
this.mTitle = mtitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认按钮文字
|
||||
*
|
||||
* @param confirmTextSize
|
||||
* @return
|
||||
*/
|
||||
public Builder confirmTextSize(int confirmTextSize) {
|
||||
this.confirmTextSize = confirmTextSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认按钮文字
|
||||
*
|
||||
* @param confirmText
|
||||
* @return
|
||||
*/
|
||||
public Builder confirmText(String confirmText) {
|
||||
this.confirmText = confirmText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认按钮文字颜色
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public Builder confirTextColor(String color) {
|
||||
this.confirmTextColorStr = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮文字颜色
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public Builder cancelTextColor(String color) {
|
||||
this.cancelTextColorStr = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮文字大小
|
||||
*
|
||||
* @param cancelTextSize
|
||||
* @return
|
||||
*/
|
||||
public Builder cancelTextSize(int cancelTextSize) {
|
||||
this.cancelTextSize = cancelTextSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮文字
|
||||
*
|
||||
* @param cancelText
|
||||
* @return
|
||||
*/
|
||||
public Builder cancelText(String cancelText) {
|
||||
this.cancelText = cancelText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*
|
||||
* @param visibleItems
|
||||
* @return
|
||||
*/
|
||||
public Builder visibleItemsCount(int visibleItems) {
|
||||
this.visibleItems = visibleItems;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 省滚轮是否循环滚动
|
||||
*
|
||||
* @param isProvinceCyclic
|
||||
* @return
|
||||
*/
|
||||
public Builder provinceCyclic(boolean isProvinceCyclic) {
|
||||
this.isProvinceCyclic = isProvinceCyclic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 市滚轮是否循环滚动
|
||||
*
|
||||
* @param isCityCyclic
|
||||
* @return
|
||||
*/
|
||||
public Builder cityCyclic(boolean isCityCyclic) {
|
||||
this.isCityCyclic = isCityCyclic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 区滚轮是否循环滚动
|
||||
*
|
||||
* @param isDistrictCyclic
|
||||
* @return
|
||||
*/
|
||||
public Builder districtCyclic(boolean isDistrictCyclic) {
|
||||
this.isDistrictCyclic = isDistrictCyclic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示半透明的背景
|
||||
*
|
||||
* @param isShowBackground
|
||||
* @return
|
||||
*/
|
||||
public Builder showBackground(boolean isShowBackground) {
|
||||
this.isShowBackground = isShowBackground;
|
||||
return this;
|
||||
}
|
||||
//
|
||||
|
||||
/**
|
||||
* 自定义item布局
|
||||
*
|
||||
* @param itemLayout
|
||||
* @return
|
||||
*/
|
||||
public Builder setCustomItemLayout(Integer itemLayout) {
|
||||
this.customItemLayout = itemLayout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义item布局中的id
|
||||
*
|
||||
* @param setCustomItemTextViewId
|
||||
* @return
|
||||
*/
|
||||
public Builder setCustomItemTextViewId(Integer setCustomItemTextViewId) {
|
||||
this.customItemTextViewId = setCustomItemTextViewId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomConfig build() {
|
||||
CustomConfig config = new CustomConfig(this);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
package com.lljjcoder.style.citycustome;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.lljjcoder.Interface.OnCustomCityPickerItemClickListener;
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.CustomCityData;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
import com.lljjcoder.citywheel.CityConfig;
|
||||
import com.lljjcoder.citywheel.CustomConfig;
|
||||
import com.lljjcoder.style.citylist.Toast.ToastUtils;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
import com.lljjcoder.style.citypickerview.widget.CanShow;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.OnWheelChangedListener;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.WheelView;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.adapters.ArrayWheelAdapter;
|
||||
import com.lljjcoder.utils.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CustomCityPicker implements CanShow, OnWheelChangedListener {
|
||||
|
||||
|
||||
private PopupWindow popwindow;
|
||||
|
||||
private View popview;
|
||||
|
||||
private WheelView mViewProvince;
|
||||
|
||||
private WheelView mViewCity;
|
||||
|
||||
private WheelView mViewDistrict;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private RelativeLayout mRelativeTitleBg;
|
||||
|
||||
private TextView mTvOK;
|
||||
|
||||
private TextView mTvTitle;
|
||||
|
||||
private TextView mTvCancel;
|
||||
|
||||
private CustomConfig config;
|
||||
|
||||
private OnCustomCityPickerItemClickListener listener = null;
|
||||
|
||||
private CustomConfig.WheelType type = CustomConfig.WheelType.PRO_CITY_DIS;
|
||||
|
||||
public void setOnCustomCityPickerItemClickListener(OnCustomCityPickerItemClickListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public CustomCityPicker(Context context) {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
public void setCustomConfig(CustomConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
|
||||
if (config == null) {
|
||||
ToastUtils.showLongToast(mContext, "请设置相关的config");
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
|
||||
popview = layoutInflater.inflate(R.layout.pop_citypicker, null);
|
||||
|
||||
mViewProvince = (WheelView) popview.findViewById(R.id.id_province);
|
||||
mViewCity = (WheelView) popview.findViewById(R.id.id_city);
|
||||
mViewDistrict = (WheelView) popview.findViewById(R.id.id_district);
|
||||
|
||||
mRelativeTitleBg = (RelativeLayout) popview.findViewById(R.id.rl_title);
|
||||
mTvOK = (TextView) popview.findViewById(R.id.tv_confirm);
|
||||
mTvTitle = (TextView) popview.findViewById(R.id.tv_title);
|
||||
mTvCancel = (TextView) popview.findViewById(R.id.tv_cancel);
|
||||
|
||||
popwindow = new PopupWindow(popview, LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
popwindow.setAnimationStyle(R.style.AnimBottom);
|
||||
popwindow.setBackgroundDrawable(new ColorDrawable());
|
||||
popwindow.setTouchable(true);
|
||||
popwindow.setOutsideTouchable(false);
|
||||
popwindow.setFocusable(true);
|
||||
|
||||
popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
if (config.isShowBackground()) {
|
||||
utils.setBackgroundAlpha(mContext, 1.0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//设置显示层级
|
||||
type = config.getWheelType();
|
||||
setWheelShowLevel(type);
|
||||
|
||||
|
||||
/**
|
||||
* 设置标题背景颜色
|
||||
*/
|
||||
if (!TextUtils.isEmpty(config.getTitleBackgroundColorStr())) {
|
||||
if (config.getTitleBackgroundColorStr().startsWith("#")) {
|
||||
mRelativeTitleBg.setBackgroundColor(Color.parseColor(config.getTitleBackgroundColorStr()));
|
||||
} else {
|
||||
mRelativeTitleBg.setBackgroundColor(Color.parseColor("#" + config.getTitleBackgroundColorStr()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//标题
|
||||
if (!TextUtils.isEmpty(config.getTitle())) {
|
||||
mTvTitle.setText(config.getTitle());
|
||||
}
|
||||
|
||||
//标题文字大小
|
||||
if (config.getTitleTextSize() > 0) {
|
||||
mTvTitle.setTextSize(config.getTitleTextSize());
|
||||
}
|
||||
|
||||
//标题文字颜色
|
||||
if (!TextUtils.isEmpty(config.getTitleTextColorStr())) {
|
||||
if (config.getTitleTextColorStr().startsWith("#")) {
|
||||
mTvTitle.setTextColor(Color.parseColor(config.getTitleTextColorStr()));
|
||||
} else {
|
||||
mTvTitle.setTextColor(Color.parseColor("#" + config.getTitleTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
//设置确认按钮文字大小颜色
|
||||
if (!TextUtils.isEmpty(config.getConfirmTextColorStr())) {
|
||||
if (config.getConfirmTextColorStr().startsWith("#")) {
|
||||
mTvOK.setTextColor(Color.parseColor(config.getConfirmTextColorStr()));
|
||||
} else {
|
||||
mTvOK.setTextColor(Color.parseColor("#" + config.getConfirmTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(config.getConfirmText())) {
|
||||
mTvOK.setText(config.getConfirmText());
|
||||
}
|
||||
|
||||
if ((config.getConfirmTextSize() > 0)) {
|
||||
mTvOK.setTextSize(config.getConfirmTextSize());
|
||||
}
|
||||
|
||||
//设置取消按钮文字颜色
|
||||
if (!TextUtils.isEmpty(config.getCancelTextColorStr())) {
|
||||
if (config.getCancelTextColorStr().startsWith("#")) {
|
||||
mTvCancel.setTextColor(Color.parseColor(config.getCancelTextColorStr()));
|
||||
} else {
|
||||
mTvCancel.setTextColor(Color.parseColor("#" + config.getCancelTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(config.getCancelText())) {
|
||||
mTvCancel.setText(config.getCancelText());
|
||||
}
|
||||
|
||||
if ((config.getCancelTextSize() > 0)) {
|
||||
mTvCancel.setTextSize(config.getCancelTextSize());
|
||||
}
|
||||
|
||||
|
||||
// 添加change事件
|
||||
mViewProvince.addChangingListener(this);
|
||||
// 添加change事件
|
||||
mViewCity.addChangingListener(this);
|
||||
// 添加change事件
|
||||
mViewDistrict.addChangingListener(this);
|
||||
// 添加onclick事件
|
||||
mTvCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onCancel();
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//确认选择
|
||||
mTvOK.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
if (type == CustomConfig.WheelType.PRO) {
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
List<CustomCityData> provinceList = config.getCityDataList();
|
||||
CustomCityData province = provinceList.get(pCurrent);
|
||||
listener.onSelected(province, new CustomCityData(), new CustomCityData());
|
||||
} else if (type == CustomConfig.WheelType.PRO_CITY) {
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
List<CustomCityData> provinceList = config.getCityDataList();
|
||||
CustomCityData province = provinceList.get(pCurrent);
|
||||
int cCurrent = mViewCity.getCurrentItem();
|
||||
List<CustomCityData> cityDataList = province.getList();
|
||||
if (cityDataList == null) return;
|
||||
CustomCityData city = cityDataList.get(cCurrent);
|
||||
listener.onSelected(province, city, new CustomCityData());
|
||||
} else if (type == CustomConfig.WheelType.PRO_CITY_DIS) {
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
List<CustomCityData> provinceList = config.getCityDataList();
|
||||
CustomCityData province = provinceList.get(pCurrent);
|
||||
int cCurrent = mViewCity.getCurrentItem();
|
||||
List<CustomCityData> cityDataList = province.getList();
|
||||
if (cityDataList == null) return;
|
||||
CustomCityData city = cityDataList.get(cCurrent);
|
||||
int dCurrent = mViewDistrict.getCurrentItem();
|
||||
List<CustomCityData> areaList = city.getList();
|
||||
if (areaList == null) return;
|
||||
CustomCityData area = areaList.get(dCurrent);
|
||||
listener.onSelected(province, city, area);
|
||||
}
|
||||
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//背景半透明
|
||||
if (config != null && config.isShowBackground()) {
|
||||
utils.setBackgroundAlpha(mContext, 0.5f);
|
||||
}
|
||||
|
||||
|
||||
//显示省市区数据
|
||||
setUpData();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示省市区等级
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
private void setWheelShowLevel(CustomConfig.WheelType type) {
|
||||
if (type == CustomConfig.WheelType.PRO) {
|
||||
mViewProvince.setVisibility(View.VISIBLE);
|
||||
mViewCity.setVisibility(View.GONE);
|
||||
mViewDistrict.setVisibility(View.GONE);
|
||||
} else if (type == CustomConfig.WheelType.PRO_CITY) {
|
||||
mViewProvince.setVisibility(View.VISIBLE);
|
||||
mViewCity.setVisibility(View.VISIBLE);
|
||||
mViewDistrict.setVisibility(View.GONE);
|
||||
} else {
|
||||
mViewProvince.setVisibility(View.VISIBLE);
|
||||
mViewCity.setVisibility(View.VISIBLE);
|
||||
mViewDistrict.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setUpData() {
|
||||
|
||||
List<CustomCityData> proArra = config.getCityDataList();
|
||||
if (proArra == null) return;
|
||||
|
||||
int provinceDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultProvinceName()) && proArra.size() > 0) {
|
||||
for (int i = 0; i < proArra.size(); i++) {
|
||||
if (proArra.get(i).getName().startsWith(config.getDefaultProvinceName())) {
|
||||
provinceDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ArrayWheelAdapter arrayWheelAdapter = new ArrayWheelAdapter<CustomCityData>(mContext, proArra);
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE && config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
arrayWheelAdapter.setItemResource(config.getCustomItemLayout());
|
||||
arrayWheelAdapter.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
arrayWheelAdapter.setItemResource(R.layout.default_item_city);
|
||||
arrayWheelAdapter.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
mViewProvince.setViewAdapter(arrayWheelAdapter);
|
||||
|
||||
//获取所设置的省的位置,直接定位到该位置
|
||||
if (-1 != provinceDefault) {
|
||||
mViewProvince.setCurrentItem(provinceDefault);
|
||||
}
|
||||
|
||||
|
||||
// 设置可见条目数量
|
||||
mViewProvince.setVisibleItems(config.getVisibleItems());
|
||||
mViewCity.setVisibleItems(config.getVisibleItems());
|
||||
mViewDistrict.setVisibleItems(config.getVisibleItems());
|
||||
mViewProvince.setCyclic(config.isProvinceCyclic());
|
||||
mViewCity.setCyclic(config.isCityCyclic());
|
||||
mViewDistrict.setCyclic(config.isDistrictCyclic());
|
||||
|
||||
//显示滚轮模糊效果
|
||||
mViewProvince.setDrawShadows(config.isDrawShadows());
|
||||
mViewCity.setDrawShadows(config.isDrawShadows());
|
||||
mViewDistrict.setDrawShadows(config.isDrawShadows());
|
||||
|
||||
//中间线的颜色及高度
|
||||
mViewProvince.setLineColorStr(config.getLineColor());
|
||||
mViewProvince.setLineWidth(config.getLineHeigh());
|
||||
mViewCity.setLineColorStr(config.getLineColor());
|
||||
mViewCity.setLineWidth(config.getLineHeigh());
|
||||
mViewDistrict.setLineColorStr(config.getLineColor());
|
||||
mViewDistrict.setLineWidth(config.getLineHeigh());
|
||||
|
||||
|
||||
if (type == CustomConfig.WheelType.PRO_CITY || type == CustomConfig.WheelType.PRO_CITY_DIS) {
|
||||
updateCities();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前的省,更新市WheelView的信息
|
||||
*/
|
||||
private void updateCities() {
|
||||
//省份滚轮滑动的当前位置
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
|
||||
//省份选中的名称
|
||||
List<CustomCityData> proArra = config.getCityDataList();
|
||||
CustomCityData mProvinceBean = proArra.get(pCurrent);
|
||||
|
||||
List<CustomCityData> pCityList = mProvinceBean.getList();
|
||||
if (pCityList == null) return;
|
||||
|
||||
|
||||
//设置最初的默认城市
|
||||
int cityDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultCityName()) && pCityList.size() > 0) {
|
||||
for (int i = 0; i < pCityList.size(); i++) {
|
||||
if (pCityList.get(i).getName().startsWith(config.getDefaultCityName())) {
|
||||
cityDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ArrayWheelAdapter cityWheel = new ArrayWheelAdapter<CustomCityData>(mContext, pCityList);
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE && config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
cityWheel.setItemResource(config.getCustomItemLayout());
|
||||
cityWheel.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
cityWheel.setItemResource(R.layout.default_item_city);
|
||||
cityWheel.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
mViewCity.setViewAdapter(cityWheel);
|
||||
if (-1 != cityDefault) {
|
||||
mViewCity.setCurrentItem(cityDefault);
|
||||
} else {
|
||||
mViewCity.setCurrentItem(0);
|
||||
}
|
||||
|
||||
|
||||
mViewCity.setViewAdapter(cityWheel);
|
||||
|
||||
if (type == CustomConfig.WheelType.PRO_CITY_DIS) {
|
||||
updateAreas();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前的市,更新区WheelView的信息
|
||||
*/
|
||||
private void updateAreas() {
|
||||
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
int cCurrent = mViewCity.getCurrentItem();
|
||||
|
||||
List<CustomCityData> provinceList = config.getCityDataList();
|
||||
CustomCityData province = provinceList.get(pCurrent);
|
||||
List<CustomCityData> cityDataList = province.getList();
|
||||
if (cityDataList == null || cityDataList.size() <= cCurrent) return;
|
||||
CustomCityData city = cityDataList.get(cCurrent);
|
||||
List<CustomCityData> areaList = city.getList();
|
||||
if (areaList == null) return;
|
||||
|
||||
|
||||
int districtDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultDistrict()) && areaList.size() > 0) {
|
||||
for (int i = 0; i < areaList.size(); i++) {
|
||||
if (areaList.get(i).getName().startsWith(config.getDefaultDistrict())) {
|
||||
districtDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter districtWheel = new ArrayWheelAdapter<CustomCityData>(mContext, areaList);
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE
|
||||
&& config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
districtWheel.setItemResource(config.getCustomItemLayout());
|
||||
districtWheel.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
districtWheel.setItemResource(R.layout.default_item_city);
|
||||
districtWheel.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
//设置默认城市
|
||||
if (-1 != districtDefault) {
|
||||
mViewDistrict.setCurrentItem(districtDefault);
|
||||
} else {
|
||||
mViewDistrict.setCurrentItem(0);
|
||||
}
|
||||
|
||||
|
||||
mViewDistrict.setViewAdapter(districtWheel);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void showCityPicker() {
|
||||
initView();
|
||||
if (!isShow()) {
|
||||
popwindow.showAtLocation(popview, Gravity.BOTTOM, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
if (isShow()) {
|
||||
popwindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShow() {
|
||||
return popwindow.isShowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(WheelView wheel, int oldValue, int newValue) {
|
||||
if (wheel == mViewProvince) {
|
||||
updateCities();
|
||||
} else if (wheel == mViewCity) {
|
||||
updateAreas();
|
||||
} else if (wheel == mViewDistrict) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
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 com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_INVALID;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2018/1/29 17:01
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class AreaAdapter extends BaseAdapter {
|
||||
|
||||
Context context;
|
||||
|
||||
List<DistrictBean> mDistrictList;
|
||||
|
||||
private int districtIndex = INDEX_INVALID;
|
||||
|
||||
public AreaAdapter(Context context, List<DistrictBean> mDistrictList) {
|
||||
this.context = context;
|
||||
this.mDistrictList = mDistrictList;
|
||||
}
|
||||
|
||||
|
||||
public int getSelectedPosition() {
|
||||
return this.districtIndex;
|
||||
}
|
||||
|
||||
public void updateSelectedPosition(int index) {
|
||||
this.districtIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mDistrictList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistrictBean getItem(int position) {
|
||||
return mDistrictList.get(position);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return Long.parseLong(mDistrictList.get(position).getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.pop_jdcitypicker_item, parent, false);
|
||||
|
||||
holder = new Holder();
|
||||
holder.name = (TextView) convertView.findViewById(R.id.name);
|
||||
holder.selectImg = (ImageView) convertView.findViewById(R.id.selectImg);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
|
||||
DistrictBean item = getItem(position);
|
||||
holder.name.setText(item.getName());
|
||||
|
||||
boolean checked = districtIndex != INDEX_INVALID && mDistrictList.get(districtIndex).getName().equals(item.getName());
|
||||
holder.name.setEnabled(!checked);
|
||||
holder.selectImg.setVisibility(checked ? View.VISIBLE : View.GONE);
|
||||
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
class Holder {
|
||||
TextView name;
|
||||
ImageView selectImg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
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 com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_INVALID;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2018/1/29 17:01
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityAdapter extends BaseAdapter {
|
||||
|
||||
Context context;
|
||||
|
||||
List<CityBean> mCityList;
|
||||
|
||||
private int cityIndex = INDEX_INVALID;
|
||||
|
||||
public CityAdapter(Context context, List<CityBean> mCityList) {
|
||||
this.context = context;
|
||||
this.mCityList = mCityList;
|
||||
}
|
||||
|
||||
public int getSelectedPosition() {
|
||||
return this.cityIndex;
|
||||
}
|
||||
|
||||
public void updateSelectedPosition(int index) {
|
||||
this.cityIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mCityList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CityBean getItem(int position) {
|
||||
return mCityList.get(position);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return Long.parseLong(mCityList.get(position).getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.pop_jdcitypicker_item, parent, false);
|
||||
|
||||
holder = new Holder();
|
||||
holder.name = (TextView) convertView.findViewById(R.id.name);
|
||||
holder.selectImg = (ImageView) convertView.findViewById(R.id.selectImg);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
|
||||
CityBean item = getItem(position);
|
||||
holder.name.setText(item.getName());
|
||||
|
||||
boolean checked = cityIndex != INDEX_INVALID && mCityList.get(cityIndex).getName().equals(item.getName());
|
||||
holder.name.setEnabled(!checked);
|
||||
holder.selectImg.setVisibility(checked ? View.VISIBLE : View.GONE);
|
||||
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
class Holder {
|
||||
TextView name;
|
||||
ImageView selectImg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
import com.lljjcoder.citywheel.CityConfig;
|
||||
|
||||
public class JDCityConfig {
|
||||
|
||||
/**
|
||||
* 默认显示的城市数据,只包含省市区名称
|
||||
* 定义显示省市区三种显示状态
|
||||
* PRO:只显示省份的一级选择器
|
||||
* PRO_CITY:显示省份和城市二级联动的选择器
|
||||
* PRO_CITY_DIS:显示省份和城市和县区三级联动的选择器
|
||||
*/
|
||||
public enum ShowType {
|
||||
PRO_CITY, PRO_CITY_DIS
|
||||
}
|
||||
|
||||
private ShowType showType = ShowType.PRO_CITY_DIS;
|
||||
|
||||
public ShowType getShowType() {
|
||||
return showType;
|
||||
}
|
||||
|
||||
public void setShowType(ShowType showType) {
|
||||
this.showType = showType;
|
||||
}
|
||||
|
||||
public JDCityConfig(Builder builder) {
|
||||
this.showType = builder.showType;
|
||||
}
|
||||
|
||||
|
||||
public static class Builder {
|
||||
|
||||
public Builder() {
|
||||
|
||||
}
|
||||
|
||||
public ShowType showType = ShowType.PRO_CITY_DIS;
|
||||
|
||||
/**
|
||||
* 显示省市区三级联动的显示状态
|
||||
* PRO_CITY:显示省份和城市二级联动的选择器
|
||||
* PRO_CITY_DIS:显示省份和城市和县区三级联动的选择器
|
||||
*
|
||||
* @param showType
|
||||
* @return
|
||||
*/
|
||||
public Builder setJDCityShowType(ShowType showType) {
|
||||
this.showType = showType;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public JDCityConfig build() {
|
||||
JDCityConfig config = new JDCityConfig(this);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
|
||||
import com.lljjcoder.Interface.OnCityItemClickListener;
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
import com.lljjcoder.citywheel.CityParseHelper;
|
||||
import com.lljjcoder.style.citylist.Toast.ToastUtils;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
import com.lljjcoder.style.citypickerview.widget.CanShow;
|
||||
import com.lljjcoder.utils.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_INVALID;
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_TAB_AREA;
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_TAB_CITY;
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_TAB_PROVINCE;
|
||||
|
||||
/**
|
||||
* 仿京东城市选择器
|
||||
* 作者:liji on 2018/1/26 16:08
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class JDCityPicker {
|
||||
|
||||
private ListView mCityListView;
|
||||
|
||||
private TextView mProTv;
|
||||
|
||||
private TextView mCityTv;
|
||||
|
||||
private TextView mAreaTv;
|
||||
private ImageView mCloseImg;
|
||||
|
||||
private PopupWindow popwindow;
|
||||
private View mSelectedLine;
|
||||
private View popview;
|
||||
|
||||
private CityParseHelper parseHelper;
|
||||
private ProvinceAdapter mProvinceAdapter;
|
||||
private CityAdapter mCityAdapter;
|
||||
private AreaAdapter mAreaAdapter;
|
||||
|
||||
private List<ProvinceBean> provinceList = null;
|
||||
private List<CityBean> cityList = null;
|
||||
private List<DistrictBean> areaList = null;
|
||||
|
||||
private int tabIndex = INDEX_TAB_PROVINCE;
|
||||
private Context context;
|
||||
private String colorSelected = "#ff181c20";
|
||||
private String colorAlert = "#ffff4444";
|
||||
|
||||
private OnCityItemClickListener mBaseListener;
|
||||
|
||||
private JDCityConfig cityConfig = null;
|
||||
|
||||
public void setOnCityItemClickListener(OnCityItemClickListener listener) {
|
||||
mBaseListener = listener;
|
||||
}
|
||||
|
||||
public void setConfig(JDCityConfig cityConfig) {
|
||||
this.cityConfig = cityConfig;
|
||||
}
|
||||
|
||||
|
||||
private void initJDCityPickerPop() {
|
||||
|
||||
if (this.cityConfig == null) {
|
||||
this.cityConfig = new JDCityConfig.Builder().setJDCityShowType(JDCityConfig.ShowType.PRO_CITY_DIS).build();
|
||||
}
|
||||
|
||||
tabIndex = INDEX_TAB_PROVINCE;
|
||||
//解析初始数据
|
||||
if (parseHelper == null) {
|
||||
parseHelper = new CityParseHelper();
|
||||
}
|
||||
|
||||
if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
|
||||
ToastUtils.showLongToast(context, "请调用init方法进行初始化相关操作");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(context);
|
||||
popview = layoutInflater.inflate(R.layout.pop_jdcitypicker, null);
|
||||
|
||||
mCityListView = (ListView) popview.findViewById(R.id.city_listview);
|
||||
mProTv = (TextView) popview.findViewById(R.id.province_tv);
|
||||
mCityTv = (TextView) popview.findViewById(R.id.city_tv);
|
||||
mAreaTv = (TextView) popview.findViewById(R.id.area_tv);
|
||||
mCloseImg = (ImageView) popview.findViewById(R.id.close_img);
|
||||
mSelectedLine = (View) popview.findViewById(R.id.selected_line);
|
||||
|
||||
popwindow = new PopupWindow(popview, LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
popwindow.setAnimationStyle(R.style.AnimBottom);
|
||||
popwindow.setBackgroundDrawable(new ColorDrawable());
|
||||
popwindow.setTouchable(true);
|
||||
popwindow.setOutsideTouchable(false);
|
||||
popwindow.setFocusable(true);
|
||||
|
||||
popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
utils.setBackgroundAlpha(context, 1.0f);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mCloseImg.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
hidePop();
|
||||
utils.setBackgroundAlpha(context, 1.0f);
|
||||
if (mBaseListener != null) {
|
||||
mBaseListener.onCancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mProTv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
tabIndex = INDEX_TAB_PROVINCE;
|
||||
if (mProvinceAdapter != null) {
|
||||
mCityListView.setAdapter(mProvinceAdapter);
|
||||
if (mProvinceAdapter.getSelectedPosition() != INDEX_INVALID) {
|
||||
mCityListView.setSelection(mProvinceAdapter.getSelectedPosition());
|
||||
}
|
||||
}
|
||||
updateTabVisible();
|
||||
updateIndicator();
|
||||
}
|
||||
});
|
||||
mCityTv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
tabIndex = INDEX_TAB_CITY;
|
||||
if (mCityAdapter != null) {
|
||||
mCityListView.setAdapter(mCityAdapter);
|
||||
if (mCityAdapter.getSelectedPosition() != INDEX_INVALID) {
|
||||
mCityListView.setSelection(mCityAdapter.getSelectedPosition());
|
||||
}
|
||||
}
|
||||
updateTabVisible();
|
||||
updateIndicator();
|
||||
}
|
||||
});
|
||||
mAreaTv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
tabIndex = INDEX_TAB_AREA;
|
||||
if (mAreaAdapter != null) {
|
||||
mCityListView.setAdapter(mAreaAdapter);
|
||||
if (mAreaAdapter.getSelectedPosition() != INDEX_INVALID) {
|
||||
mCityListView.setSelection(mAreaAdapter.getSelectedPosition());
|
||||
}
|
||||
}
|
||||
updateTabVisible();
|
||||
updateIndicator();
|
||||
}
|
||||
});
|
||||
mCityListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
selectedList(position);
|
||||
}
|
||||
});
|
||||
|
||||
utils.setBackgroundAlpha(context, 0.5f);
|
||||
updateIndicator();
|
||||
updateTabsStyle(INDEX_INVALID);
|
||||
setProvinceListData();
|
||||
|
||||
}
|
||||
|
||||
private void selectedList(int position) {
|
||||
switch (tabIndex) {
|
||||
case INDEX_TAB_PROVINCE:
|
||||
ProvinceBean provinceBean = mProvinceAdapter.getItem(position);
|
||||
if (provinceBean != null) {
|
||||
mProTv.setText("" + provinceBean.getName());
|
||||
mCityTv.setText("请选择");
|
||||
mProvinceAdapter.updateSelectedPosition(position);
|
||||
mProvinceAdapter.notifyDataSetChanged();
|
||||
mCityAdapter = new CityAdapter(context, provinceBean.getCityList());
|
||||
//选中省份数据后更新市数据
|
||||
mHandler.sendMessage(Message.obtain(mHandler, INDEX_TAB_CITY, provinceBean.getCityList()));
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case INDEX_TAB_CITY:
|
||||
CityBean cityBean = mCityAdapter.getItem(position);
|
||||
if (cityBean != null) {
|
||||
mCityTv.setText("" + cityBean.getName());
|
||||
mAreaTv.setText("请选择");
|
||||
mCityAdapter.updateSelectedPosition(position);
|
||||
mCityAdapter.notifyDataSetChanged();
|
||||
if (this.cityConfig != null && this.cityConfig.getShowType() == JDCityConfig.ShowType.PRO_CITY) {
|
||||
callback(new DistrictBean());
|
||||
} else {
|
||||
mAreaAdapter = new AreaAdapter(context, cityBean.getCityList());
|
||||
//选中省份数据后更新市数据
|
||||
mHandler.sendMessage(Message.obtain(mHandler, INDEX_TAB_AREA, cityBean.getCityList()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case INDEX_TAB_AREA:
|
||||
//返回选中的省市区数据
|
||||
DistrictBean districtBean = mAreaAdapter.getItem(position);
|
||||
if (districtBean != null) {
|
||||
callback(districtBean);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认的省份数据
|
||||
*/
|
||||
private void setProvinceListData() {
|
||||
provinceList = parseHelper.getProvinceBeanArrayList();
|
||||
if (provinceList != null && !provinceList.isEmpty()) {
|
||||
mProvinceAdapter = new ProvinceAdapter(context, provinceList);
|
||||
mCityListView.setAdapter(mProvinceAdapter);
|
||||
} else {
|
||||
ToastUtils.showLongToast(context, "解析本地城市数据失败!");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化,默认解析城市数据,提交加载速度
|
||||
*/
|
||||
public void init(Context context) {
|
||||
this.context = context;
|
||||
parseHelper = new CityParseHelper();
|
||||
|
||||
//解析初始数据
|
||||
if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
|
||||
parseHelper.initData(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新选中城市下面的红色横线指示器
|
||||
*/
|
||||
private void updateIndicator() {
|
||||
popview.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (tabIndex) {
|
||||
case INDEX_TAB_PROVINCE:
|
||||
tabSelectedIndicatorAnimation(mProTv).start();
|
||||
break;
|
||||
case INDEX_TAB_CITY:
|
||||
tabSelectedIndicatorAnimation(mCityTv).start();
|
||||
break;
|
||||
case INDEX_TAB_AREA:
|
||||
tabSelectedIndicatorAnimation(mAreaTv).start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* tab 选中的红色下划线动画
|
||||
*
|
||||
* @param tab
|
||||
* @return
|
||||
*/
|
||||
private AnimatorSet tabSelectedIndicatorAnimation(TextView tab) {
|
||||
ObjectAnimator xAnimator = ObjectAnimator.ofFloat(mSelectedLine, "X", mSelectedLine.getX(), tab.getX());
|
||||
|
||||
final ViewGroup.LayoutParams params = mSelectedLine.getLayoutParams();
|
||||
ValueAnimator widthAnimator = ValueAnimator.ofInt(params.width, tab.getMeasuredWidth());
|
||||
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
params.width = (int) animation.getAnimatedValue();
|
||||
mSelectedLine.setLayoutParams(params);
|
||||
}
|
||||
});
|
||||
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.setInterpolator(new FastOutSlowInInterpolator());
|
||||
set.playTogether(xAnimator, widthAnimator);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public void showCityPicker() {
|
||||
initJDCityPickerPop();
|
||||
if (!isShow()) {
|
||||
popwindow.showAtLocation(popview, Gravity.BOTTOM, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void hidePop() {
|
||||
if (isShow()) {
|
||||
popwindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isShow() {
|
||||
return popwindow.isShowing();
|
||||
}
|
||||
|
||||
|
||||
private void updateTabVisible() {
|
||||
mProTv.setVisibility(provinceList == null || provinceList.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
mCityTv.setVisibility(cityList == null || cityList.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
mAreaTv.setVisibility(areaList == null || areaList.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 选择回调
|
||||
*
|
||||
* @param districtBean
|
||||
*/
|
||||
private void callback(DistrictBean districtBean) {
|
||||
|
||||
ProvinceBean provinceBean = provinceList != null &&
|
||||
!provinceList.isEmpty() &&
|
||||
mProvinceAdapter != null &&
|
||||
mProvinceAdapter.getSelectedPosition() != INDEX_INVALID ?
|
||||
provinceList.get(mProvinceAdapter.getSelectedPosition()) : null;
|
||||
|
||||
CityBean cityBean = cityList != null &&
|
||||
!cityList.isEmpty() &&
|
||||
mCityAdapter != null &&
|
||||
mCityAdapter.getSelectedPosition() != INDEX_INVALID ?
|
||||
cityList.get(mCityAdapter.getSelectedPosition()) : null;
|
||||
|
||||
mBaseListener.onSelected(provinceBean, cityBean, districtBean);
|
||||
hidePop();
|
||||
|
||||
}
|
||||
|
||||
private Handler mHandler = new Handler(new Handler.Callback() {
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case INDEX_INVALID:
|
||||
provinceList = (List<ProvinceBean>) msg.obj;
|
||||
mProvinceAdapter.notifyDataSetChanged();
|
||||
mCityListView.setAdapter(mProvinceAdapter);
|
||||
|
||||
break;
|
||||
|
||||
case INDEX_TAB_PROVINCE:
|
||||
provinceList = (List<ProvinceBean>) msg.obj;
|
||||
mProvinceAdapter.notifyDataSetChanged();
|
||||
mCityListView.setAdapter(mProvinceAdapter);
|
||||
break;
|
||||
|
||||
|
||||
case INDEX_TAB_CITY:
|
||||
cityList = (List<CityBean>) msg.obj;
|
||||
mCityAdapter.notifyDataSetChanged();
|
||||
if (cityList != null && !cityList.isEmpty()) {
|
||||
mCityListView.setAdapter(mCityAdapter);
|
||||
tabIndex = INDEX_TAB_CITY;
|
||||
}
|
||||
break;
|
||||
|
||||
case INDEX_TAB_AREA:
|
||||
areaList = (List<DistrictBean>) msg.obj;
|
||||
mAreaAdapter.notifyDataSetChanged();
|
||||
if (areaList != null && !areaList.isEmpty()) {
|
||||
mCityListView.setAdapter(mAreaAdapter);
|
||||
tabIndex = INDEX_TAB_AREA;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
updateTabsStyle(tabIndex);
|
||||
updateIndicator();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 设置选中的城市tab是否可见
|
||||
*/
|
||||
private void updateTabsStyle(int tabIndex) {
|
||||
switch (tabIndex) {
|
||||
case INDEX_INVALID:
|
||||
mProTv.setTextColor(Color.parseColor(colorAlert));
|
||||
mProTv.setVisibility(View.VISIBLE);
|
||||
mCityTv.setVisibility(View.GONE);
|
||||
mAreaTv.setVisibility(View.GONE);
|
||||
|
||||
break;
|
||||
|
||||
case INDEX_TAB_PROVINCE:
|
||||
mProTv.setTextColor(Color.parseColor(colorAlert));
|
||||
mProTv.setVisibility(View.VISIBLE);
|
||||
mCityTv.setVisibility(View.GONE);
|
||||
mAreaTv.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
|
||||
case INDEX_TAB_CITY:
|
||||
mProTv.setTextColor(Color.parseColor(colorSelected));
|
||||
mCityTv.setTextColor(Color.parseColor(colorAlert));
|
||||
mProTv.setVisibility(View.VISIBLE);
|
||||
mCityTv.setVisibility(View.VISIBLE);
|
||||
mAreaTv.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case INDEX_TAB_AREA:
|
||||
mProTv.setTextColor(Color.parseColor(colorSelected));
|
||||
mCityTv.setTextColor(Color.parseColor(colorSelected));
|
||||
mAreaTv.setTextColor(Color.parseColor(colorAlert));
|
||||
mProTv.setVisibility(View.VISIBLE);
|
||||
mCityTv.setVisibility(View.VISIBLE);
|
||||
mAreaTv.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
public class JDConst {
|
||||
|
||||
public static final int INDEX_TAB_PROVINCE = 0;
|
||||
public static final int INDEX_TAB_CITY = 1;
|
||||
public static final int INDEX_TAB_AREA = 2;
|
||||
|
||||
public static final int INDEX_INVALID = -1;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class MyListView extends ListView {
|
||||
public MyListView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MyListView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.lljjcoder.style.cityjd;
|
||||
|
||||
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 com.lljjcoder.bean.ProvinceBean;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.cityjd.JDConst.INDEX_INVALID;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2018/1/29 17:01
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class ProvinceAdapter extends BaseAdapter {
|
||||
|
||||
Context context;
|
||||
|
||||
List<ProvinceBean> mProList;
|
||||
|
||||
private int provinceIndex = INDEX_INVALID;
|
||||
|
||||
public ProvinceAdapter(Context context, List<ProvinceBean> mProList) {
|
||||
this.context = context;
|
||||
this.mProList = mProList;
|
||||
}
|
||||
|
||||
public void updateSelectedPosition(int index) {
|
||||
this.provinceIndex = index;
|
||||
}
|
||||
|
||||
public int getSelectedPosition() {
|
||||
return this.provinceIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mProList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProvinceBean getItem(int position) {
|
||||
return mProList.get(position);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return Long.parseLong(mProList.get(position).getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Holder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.pop_jdcitypicker_item, parent, false);
|
||||
|
||||
holder = new Holder();
|
||||
holder.name = (TextView) convertView.findViewById(R.id.name);
|
||||
holder.selectImg = (ImageView) convertView.findViewById(R.id.selectImg);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
|
||||
ProvinceBean item = getItem(position);
|
||||
holder.name.setText(item.getName());
|
||||
|
||||
boolean checked = provinceIndex != INDEX_INVALID && mProList.get(provinceIndex).getName().equals(item.getName());
|
||||
holder.name.setEnabled(!checked);
|
||||
holder.selectImg.setVisibility(checked ? View.VISIBLE : View.GONE);
|
||||
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
class Holder {
|
||||
TextView name;
|
||||
ImageView selectImg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.lljjcoder.style.citylist;
|
||||
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/5/21 16:23
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CConfig {
|
||||
|
||||
private static CityInfoBean sCityInfoBean;
|
||||
|
||||
public static void setCity(CityInfoBean city) {
|
||||
sCityInfoBean = city;
|
||||
}
|
||||
|
||||
public static CityInfoBean getCitySelected() {
|
||||
|
||||
return sCityInfoBean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
package com.lljjcoder.style.citylist;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.promeg.pinyinhelper.Pinyin;
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
import com.lljjcoder.style.citylist.sortlistview.CharacterParser;
|
||||
import com.lljjcoder.style.citylist.sortlistview.PinyinComparator;
|
||||
import com.lljjcoder.style.citylist.sortlistview.SideBar;
|
||||
import com.lljjcoder.style.citylist.sortlistview.SortAdapter;
|
||||
import com.lljjcoder.style.citylist.sortlistview.SortModel;
|
||||
import com.lljjcoder.style.citylist.utils.CityListLoader;
|
||||
import com.lljjcoder.style.citylist.widget.CleanableEditView;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CityListSelectActivity extends Activity {
|
||||
|
||||
CleanableEditView mCityTextSearch;
|
||||
|
||||
TextView mCurrentCityTag;
|
||||
|
||||
TextView mCurrentCity;
|
||||
|
||||
TextView mLocalCityTag;
|
||||
|
||||
TextView mLocalCity;
|
||||
|
||||
ListView sortListView;
|
||||
|
||||
TextView mDialog;
|
||||
|
||||
SideBar mSidrbar;
|
||||
|
||||
ImageView imgBack;
|
||||
|
||||
public SortAdapter adapter;
|
||||
|
||||
/**
|
||||
* 汉字转换成拼音的类
|
||||
*/
|
||||
private CharacterParser characterParser;
|
||||
|
||||
private List<SortModel> sourceDateList;
|
||||
|
||||
/**
|
||||
* 根据拼音来排列ListView里面的数据类
|
||||
*/
|
||||
private PinyinComparator pinyinComparator;
|
||||
|
||||
private List<CityInfoBean> cityListInfo = new ArrayList<>();
|
||||
|
||||
private CityInfoBean cityInfoBean = new CityInfoBean();
|
||||
|
||||
//startActivityForResult flag
|
||||
public static final int CITY_SELECT_RESULT_FRAG = 0x0000032;
|
||||
|
||||
public static List<CityInfoBean> sCityInfoBeanList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_city_list_select);
|
||||
|
||||
initView();
|
||||
|
||||
initList();
|
||||
|
||||
setCityData(CityListLoader.getInstance().getCityListData());
|
||||
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mCityTextSearch = (CleanableEditView) findViewById(R.id.cityInputText);
|
||||
mCurrentCityTag = (TextView) findViewById(R.id.currentCityTag);
|
||||
mCurrentCity = (TextView) findViewById(R.id.currentCity);
|
||||
mLocalCityTag = (TextView) findViewById(R.id.localCityTag);
|
||||
mLocalCity = (TextView) findViewById(R.id.localCity);
|
||||
sortListView = (ListView) findViewById(R.id.country_lvcountry);
|
||||
mDialog = (TextView) findViewById(R.id.dialog);
|
||||
mSidrbar = (SideBar) findViewById(R.id.sidrbar);
|
||||
imgBack = (ImageView) findViewById(R.id.imgBack);
|
||||
imgBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setCityData(List<CityInfoBean> cityList) {
|
||||
cityListInfo = cityList;
|
||||
if (cityListInfo == null) {
|
||||
return;
|
||||
}
|
||||
int count = cityList.size();
|
||||
String[] list = new String[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
list[i] = cityList.get(i).getName();
|
||||
|
||||
sourceDateList.addAll(filledData(cityList));
|
||||
// 根据a-z进行排序源数据
|
||||
Collections.sort(sourceDateList, pinyinComparator);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 为ListView填充数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<SortModel> filledData(List<CityInfoBean> cityList) {
|
||||
List<SortModel> mSortList = new ArrayList<SortModel>();
|
||||
|
||||
for (int i = 0; i < cityList.size(); i++) {
|
||||
|
||||
CityInfoBean result = cityList.get(i);
|
||||
|
||||
if (result != null) {
|
||||
|
||||
SortModel sortModel = new SortModel();
|
||||
|
||||
String cityName = result.getName();
|
||||
//汉字转换成拼音
|
||||
if (!TextUtils.isEmpty(cityName) && cityName.length() > 0) {
|
||||
|
||||
// String pinyin = "";
|
||||
// if (cityName.equals("重庆市")) {
|
||||
// pinyin = "chong";
|
||||
// }
|
||||
// else if (cityName.equals("长沙市")) {
|
||||
// pinyin = "chang";
|
||||
// }
|
||||
// else if (cityName.equals("长春市")) {
|
||||
// pinyin = "chang";
|
||||
// }
|
||||
// else {
|
||||
// pinyin = mPinYinUtils.getStringPinYin(cityName.substring(0, 1));
|
||||
// }
|
||||
//
|
||||
String pinyin = Pinyin.toPinyin(cityName.substring(0, 1), "").toLowerCase();
|
||||
if (!TextUtils.isEmpty(pinyin)) {
|
||||
|
||||
sortModel.setName(cityName);
|
||||
|
||||
String sortString = pinyin.substring(0, 1).toUpperCase();
|
||||
|
||||
// 正则表达式,判断首字母是否是英文字母
|
||||
if (sortString.matches("[A-Z]")) {
|
||||
sortModel.setSortLetters(sortString.toUpperCase());
|
||||
} else {
|
||||
sortModel.setSortLetters("#");
|
||||
}
|
||||
mSortList.add(sortModel);
|
||||
} else {
|
||||
Log.d("citypicker_log", "null,cityName:-> " + cityName + " pinyin:-> " + pinyin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return mSortList;
|
||||
}
|
||||
|
||||
private void initList() {
|
||||
sourceDateList = new ArrayList<SortModel>();
|
||||
adapter = new SortAdapter(CityListSelectActivity.this, sourceDateList);
|
||||
sortListView.setAdapter(adapter);
|
||||
|
||||
//实例化汉字转拼音类
|
||||
characterParser = CharacterParser.getInstance();
|
||||
pinyinComparator = new PinyinComparator();
|
||||
mSidrbar.setTextView(mDialog);
|
||||
//设置右侧触摸监听
|
||||
mSidrbar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {
|
||||
|
||||
@Override
|
||||
public void onTouchingLetterChanged(String s) {
|
||||
//该字母首次出现的位置
|
||||
int position = adapter.getPositionForSection(s.charAt(0));
|
||||
if (position != -1) {
|
||||
sortListView.setSelection(position);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sortListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
String cityName = ((SortModel) adapter.getItem(position)).getName();
|
||||
cityInfoBean = CityInfoBean.findCity(cityListInfo, cityName);
|
||||
Intent intent = new Intent();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable("cityinfo", cityInfoBean);
|
||||
intent.putExtras(bundle);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
//根据输入框输入值的改变来过滤搜索
|
||||
mCityTextSearch.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
//当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
|
||||
filterData(s.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据输入框中的值来过滤数据并更新ListView
|
||||
*
|
||||
* @param filterStr
|
||||
*/
|
||||
private void filterData(String filterStr) {
|
||||
List<SortModel> filterDateList = new ArrayList<SortModel>();
|
||||
|
||||
if (TextUtils.isEmpty(filterStr)) {
|
||||
filterDateList = sourceDateList;
|
||||
} else {
|
||||
filterDateList.clear();
|
||||
for (SortModel sortModel : sourceDateList) {
|
||||
String name = sortModel.getName();
|
||||
if (name.contains(filterStr) || characterParser.getSelling(name).startsWith(filterStr)) {
|
||||
filterDateList.add(sortModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据a-z进行排序
|
||||
Collections.sort(filterDateList, pinyinComparator);
|
||||
adapter.updateListView(filterDateList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.lljjcoder.style.citylist.Toast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
|
||||
/**
|
||||
* author:admin on 2016/5/4 10:50
|
||||
* email:fangkaijin@gmail.com
|
||||
*/
|
||||
public class AlarmDailog extends Toast
|
||||
{
|
||||
private Toast toast;
|
||||
private Context context;
|
||||
private TextView noticeText;
|
||||
|
||||
public AlarmDailog(Context context)
|
||||
{
|
||||
super(context);
|
||||
this.context = context;
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
View layout = inflater.inflate( R.layout.dialog_alarm_ui, null);
|
||||
noticeText = (TextView) layout.findViewById( R.id.noticeText);
|
||||
toast = new Toast(context);
|
||||
toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
|
||||
toast.setDuration(Toast.LENGTH_SHORT);
|
||||
//让Toast显示为我们自定义的样子
|
||||
toast.setView(layout);
|
||||
}
|
||||
|
||||
public void setShowText(String dialogNotice)
|
||||
{
|
||||
noticeText.setText(dialogNotice);
|
||||
}
|
||||
|
||||
public void show()
|
||||
{
|
||||
toast.show();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.lljjcoder.style.citylist.Toast;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* author:admin on 2016/5/4 10:49
|
||||
* email:fangkaijin@gmail.com
|
||||
*/
|
||||
public class ToastUtils {
|
||||
|
||||
private static AlarmDailog alarmDialog;
|
||||
|
||||
public static
|
||||
void showShortToast (Context context, String showMsg ) {
|
||||
if ( null != alarmDialog ) {
|
||||
alarmDialog = null;
|
||||
}
|
||||
alarmDialog = new AlarmDailog(context);
|
||||
alarmDialog.setShowText(showMsg);
|
||||
alarmDialog.setDuration(Toast.LENGTH_SHORT);
|
||||
alarmDialog.show();
|
||||
|
||||
}
|
||||
|
||||
public static void showLongToast(Context context, String showMsg)
|
||||
{
|
||||
if (null != alarmDialog)
|
||||
{
|
||||
alarmDialog = null;
|
||||
}
|
||||
alarmDialog = new AlarmDailog(context);
|
||||
alarmDialog.setShowText(showMsg);
|
||||
alarmDialog.show();
|
||||
}
|
||||
|
||||
public static void showMomentToast(final Activity activity, final Context context, final String showMsg)
|
||||
{
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (null == alarmDialog)
|
||||
{
|
||||
alarmDialog = new AlarmDailog(context);
|
||||
alarmDialog.setShowText(showMsg);
|
||||
alarmDialog.setDuration(Toast.LENGTH_SHORT);
|
||||
alarmDialog.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
alarmDialog.setShowText(showMsg);
|
||||
alarmDialog.show();
|
||||
}
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
if(null != alarmDialog)
|
||||
{
|
||||
alarmDialog.cancel();
|
||||
}
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.lljjcoder.style.citylist.bean;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/5/19 17:07
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityInfoBean implements Parcelable {
|
||||
|
||||
|
||||
private String id; /*110101*/
|
||||
|
||||
private String name; /*东城区*/
|
||||
|
||||
private ArrayList<CityInfoBean> cityList;
|
||||
|
||||
public ArrayList<CityInfoBean> getCityList() {
|
||||
return cityList;
|
||||
}
|
||||
|
||||
public void setCityList(ArrayList<CityInfoBean> cityList) {
|
||||
this.cityList = cityList;
|
||||
}
|
||||
|
||||
public CityInfoBean() {
|
||||
}
|
||||
|
||||
public static CityInfoBean findCity(List<CityInfoBean> list, String cityName) {
|
||||
try {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CityInfoBean city = list.get(i);
|
||||
if (cityName.equals(city.getName()) /*|| cityName.contains(city.getName())
|
||||
|| city.getName().contains(cityName)*/) {
|
||||
return city;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id == null ? "" : id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.name);
|
||||
dest.writeTypedList(this.cityList);
|
||||
}
|
||||
|
||||
protected CityInfoBean(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.name = in.readString();
|
||||
this.cityList = in.createTypedArrayList(CityInfoBean.CREATOR);
|
||||
}
|
||||
|
||||
public static final Creator<CityInfoBean> CREATOR = new Creator<CityInfoBean>() {
|
||||
@Override
|
||||
public CityInfoBean createFromParcel(Parcel source) {
|
||||
return new CityInfoBean(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CityInfoBean[] newArray(int size) {
|
||||
return new CityInfoBean[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
|
||||
package com.lljjcoder.style.citylist.sortlistview;
|
||||
|
||||
/**
|
||||
* Java汉字转换为拼音
|
||||
*
|
||||
*/
|
||||
public class CharacterParser {
|
||||
private static int[] pyvalue = new int[] {-20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032,
|
||||
-20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, -19746, -19741, -19739, -19728,
|
||||
-19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, -19275, -19270, -19263, -19261,
|
||||
-19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, -19006, -19003, -18996, -18977, -18961,
|
||||
-18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, -18697, -18696, -18526, -18518, -18501, -18490,
|
||||
-18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, -18201, -18184, -18183, -18181, -18012, -17997, -17988,
|
||||
-17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, -17752, -17733, -17730, -17721, -17703, -17701, -17697, -17692,
|
||||
-17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, -17427, -17417, -17202, -17185, -16983, -16970, -16942, -16915, -16733,
|
||||
-16708, -16706, -16689, -16664, -16657, -16647, -16474, -16470, -16465, -16459, -16452, -16448, -16433, -16429, -16427, -16423, -16419,
|
||||
-16412, -16407, -16403, -16401, -16393, -16220, -16216, -16212, -16205, -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959,
|
||||
-15958, -15944, -15933, -15920, -15915, -15903, -15889, -15878, -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631,
|
||||
-15625, -15454, -15448, -15436, -15435, -15419, -15416, -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180,
|
||||
-15165, -15158, -15153, -15150, -15149, -15144, -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110, -15109, -14941,
|
||||
-14937, -14933, -14930, -14929, -14928, -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889, -14882, -14873, -14871, -14857,
|
||||
-14678, -14674, -14670, -14668, -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384, -14379, -14368, -14355, -14353,
|
||||
-14345, -14170, -14159, -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112, -14109, -14099, -14097, -14094,
|
||||
-14092, -14090, -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878, -13870, -13859, -13847, -13831,
|
||||
-13658, -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359, -13356, -13343, -13340, -13329,
|
||||
-13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060, -12888, -12875, -12871, -12860,
|
||||
-12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, -12556, -12359, -12346, -12320, -12300,
|
||||
-12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, -11798, -11781, -11604, -11589, -11536, -11358,
|
||||
-11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, -11041, -11038, -11024, -11020, -11019, -11018, -11014,
|
||||
-10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, -10533, -10519, -10331, -10329, -10328, -10322, -10315, -10309,
|
||||
-10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, -10254};
|
||||
public static String[] pystr = new String[] {"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian",
|
||||
"biao", "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai", "chan", "chang", "chao", "che",
|
||||
"chen", "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci", "cong", "cou", "cu", "cuan",
|
||||
"cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du",
|
||||
"duan", "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang",
|
||||
"gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", "hai", "han", "hang",
|
||||
"hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun", "huo", "ji", "jia", "jian",
|
||||
"jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "ken",
|
||||
"keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng",
|
||||
"li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan", "lue", "lun", "luo", "ma", "mai",
|
||||
"man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na", "nai",
|
||||
"nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", "ning", "niu", "nong", "nu", "nv", "nuan",
|
||||
"nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", "pian", "piao", "pie", "pin", "ping", "po", "pu",
|
||||
"qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re",
|
||||
"ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sen", "seng", "sha",
|
||||
"shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui", "shun",
|
||||
"shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te", "teng", "ti", "tian", "tiao",
|
||||
"tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", "wang", "wei", "wen", "weng", "wo", "wu", "xi",
|
||||
"xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi",
|
||||
"yin", "ying", "yo", "yong", "you", "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha",
|
||||
"zhai", "zhan", "zhang", "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui",
|
||||
"zhun", "zhuo", "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo"};
|
||||
|
||||
private StringBuilder buffer;
|
||||
private String resource;
|
||||
private static CharacterParser characterParser = new CharacterParser();
|
||||
|
||||
public static CharacterParser getInstance() {
|
||||
return characterParser;
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/** * 汉字转成ASCII码 * * @param chs * @return */
|
||||
private int getChsAscii(String chs) {
|
||||
int asc = 0;
|
||||
try {
|
||||
byte[] bytes = chs.getBytes("gb2312");
|
||||
if (bytes == null || bytes.length > 2 || bytes.length <= 0) {
|
||||
throw new RuntimeException("illegal resource string");
|
||||
}
|
||||
if (bytes.length == 1) {
|
||||
asc = bytes[0];
|
||||
}
|
||||
if (bytes.length == 2) {
|
||||
int hightByte = 256 + bytes[0];
|
||||
int lowByte = 256 + bytes[1];
|
||||
asc = (256 * hightByte + lowByte) - 256 * 256;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR:ChineseSpelling.class-getChsAscii(String chs)" + e);
|
||||
}
|
||||
return asc;
|
||||
}
|
||||
|
||||
/** * 单字解析 * * @param str * @return */
|
||||
public String convert(String str) {
|
||||
String result = null;
|
||||
int ascii = getChsAscii(str);
|
||||
if (ascii > 0 && ascii < 160) {
|
||||
result = String.valueOf((char) ascii);
|
||||
} else {
|
||||
for (int i = (pyvalue.length - 1); i >= 0; i--) {
|
||||
if (pyvalue[i] <= ascii) {
|
||||
result = pystr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** * 词组解析 * * @param chs * @return */
|
||||
public String getSelling(String chs) {
|
||||
String key, value;
|
||||
buffer = new StringBuilder();
|
||||
for (int i = 0; i < chs.length(); i++) {
|
||||
key = chs.substring(i, i + 1);
|
||||
if (key.getBytes().length >= 2) {
|
||||
value = (String) convert(key);
|
||||
if (value == null) {
|
||||
value = "unknown";
|
||||
}
|
||||
} else {
|
||||
value = key;
|
||||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public String getSpelling() {
|
||||
return this.getSelling(this.getResource());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lljjcoder.style.citylist.sortlistview;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xiaanming
|
||||
*
|
||||
*/
|
||||
public class PinyinComparator implements Comparator<SortModel> {
|
||||
|
||||
public int compare(SortModel o1, SortModel o2) {
|
||||
if (o1.getSortLetters().equals("@")
|
||||
|| o2.getSortLetters().equals("#")) {
|
||||
return -1;
|
||||
} else if (o1.getSortLetters().equals("#")
|
||||
|| o2.getSortLetters().equals("@")) {
|
||||
return 1;
|
||||
} else {
|
||||
return o1.getSortLetters().compareTo(o2.getSortLetters());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.lljjcoder.style.citylist.sortlistview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
|
||||
public class SideBar extends View {
|
||||
// 触摸事件
|
||||
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
|
||||
// 26个字母
|
||||
public static String[] b = { "A", "B", "C", "D", "E", "F", "G", "H", "I",
|
||||
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
|
||||
"W", "X", "Y", "Z", "#" };
|
||||
private int choose = -1;// 选中
|
||||
private Paint paint = new Paint();
|
||||
|
||||
private TextView mTextDialog;
|
||||
|
||||
public void setTextView(TextView mTextDialog) {
|
||||
this.mTextDialog = mTextDialog;
|
||||
}
|
||||
|
||||
|
||||
public SideBar(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public SideBar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SideBar(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写这个方法
|
||||
*/
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
// 获取焦点改变背景颜色.
|
||||
int height = getHeight();// 获取对应高度
|
||||
int width = getWidth(); // 获取对应宽度
|
||||
int singleHeight = height / b.length;// 获取每一个字母的高度
|
||||
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
paint.setColor(Color.rgb(33, 65, 98));
|
||||
// paint.setColor(Color.WHITE);
|
||||
paint.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setTextSize(20);
|
||||
// 选中的状态
|
||||
if (i == choose) {
|
||||
paint.setColor(Color.parseColor("#000000"));
|
||||
paint.setFakeBoldText(true);
|
||||
}
|
||||
// x坐标等于中间-字符串宽度的一半.
|
||||
float xPos = width / 2 - paint.measureText(b[i]) / 2;
|
||||
float yPos = singleHeight * i + singleHeight;
|
||||
canvas.drawText(b[i], xPos, yPos, paint);
|
||||
paint.reset();// 重置画笔
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||
final int action = event.getAction();
|
||||
final float y = event.getY();// 点击y坐标
|
||||
final int oldChoose = choose;
|
||||
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
|
||||
final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_UP:
|
||||
setBackgroundDrawable(new ColorDrawable(0x00000000));
|
||||
choose = -1;//
|
||||
invalidate();
|
||||
if (mTextDialog != null) {
|
||||
mTextDialog.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
setBackgroundResource(R.drawable.sidebar_background);
|
||||
if (oldChoose != c) {
|
||||
if (c >= 0 && c < b.length) {
|
||||
if (listener != null) {
|
||||
listener.onTouchingLetterChanged(b[c]);
|
||||
}
|
||||
if (mTextDialog != null) {
|
||||
mTextDialog.setText(b[c]);
|
||||
mTextDialog.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
choose = c;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向外公开的方法
|
||||
*
|
||||
* @param onTouchingLetterChangedListener
|
||||
*/
|
||||
public void setOnTouchingLetterChangedListener(
|
||||
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
|
||||
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口
|
||||
*
|
||||
* @author coder
|
||||
*
|
||||
*/
|
||||
public interface OnTouchingLetterChangedListener {
|
||||
public void onTouchingLetterChanged(String s);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.lljjcoder.style.citylist.sortlistview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.SectionIndexer;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SortAdapter extends BaseAdapter implements SectionIndexer {
|
||||
private List<SortModel> list = null;
|
||||
private Context mContext;
|
||||
|
||||
public SortAdapter(Context mContext, List<SortModel> list) {
|
||||
this.mContext = mContext;
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当ListView数据发生变化时,调用此方法来更新ListView
|
||||
* @param list
|
||||
*/
|
||||
public void updateListView(List<SortModel> list){
|
||||
this.list = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.list.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return list.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public View getView(final int position, View view, ViewGroup arg2) {
|
||||
ViewHolder viewHolder = null;
|
||||
if (view == null) {
|
||||
viewHolder = new ViewHolder();
|
||||
view = LayoutInflater.from(mContext).inflate(R.layout.sortlistview_item, null);
|
||||
viewHolder.tvTitle = (TextView) view.findViewById(R.id.title);
|
||||
viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog);
|
||||
view.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (ViewHolder) view.getTag();
|
||||
}
|
||||
if(null!=list&&!list.isEmpty())
|
||||
{
|
||||
SortModel mContent = list.get(position);
|
||||
//根据position获取分类的首字母的Char ascii值
|
||||
int section = getSectionForPosition(position);
|
||||
|
||||
//如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
|
||||
if(position == getPositionForSection(section)){
|
||||
viewHolder.tvLetter.setVisibility(View.VISIBLE);
|
||||
viewHolder.tvLetter.setText(mContent.getSortLetters());
|
||||
}else{
|
||||
viewHolder.tvLetter.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
viewHolder.tvTitle.setText(this.list.get(position).getName());
|
||||
}
|
||||
|
||||
return view;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
final static class ViewHolder {
|
||||
TextView tvLetter;
|
||||
TextView tvTitle;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据ListView的当前位置获取分类的首字母的Char ascii值
|
||||
*/
|
||||
public int getSectionForPosition(int position) {
|
||||
return list.get(position).getSortLetters().charAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类的首字母的Char ascii值获取其第一次出现该首字母的位置
|
||||
*/
|
||||
public int getPositionForSection(int section) {
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
String sortStr = list.get(i).getSortLetters();
|
||||
char firstChar = sortStr.toUpperCase().charAt(0);
|
||||
if (firstChar == section) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取英文的首字母,非英文字母用#代替。
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
private String getAlpha(String str) {
|
||||
String sortStr = str.trim().substring(0, 1).toUpperCase();
|
||||
// 正则表达式,判断首字母是否是英文字母
|
||||
if (sortStr.matches("[A-Z]")) {
|
||||
return sortStr;
|
||||
} else {
|
||||
return "#";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getSections() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lljjcoder.style.citylist.sortlistview;
|
||||
|
||||
public class SortModel {
|
||||
|
||||
private String name; //显示的数据
|
||||
private String sortLetters; //显示数据拼音的首字母
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getSortLetters() {
|
||||
return sortLetters;
|
||||
}
|
||||
public void setSortLetters(String sortLetters) {
|
||||
this.sortLetters = sortLetters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.lljjcoder.style.citylist.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.lljjcoder.Constant;
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
import com.lljjcoder.utils.utils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/5/21 15:35
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityListLoader {
|
||||
|
||||
public static final String BUNDATA = "bundata";
|
||||
|
||||
private static List<CityInfoBean> mCityListData = new ArrayList<>();
|
||||
|
||||
private static List<CityInfoBean> mProListData = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 解析所有的城市数据 357个数据
|
||||
*/
|
||||
public List<CityInfoBean> getCityListData() {
|
||||
return mCityListData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 只解析省份34个数据
|
||||
*/
|
||||
public List<CityInfoBean> getProListData() {
|
||||
return mProListData;
|
||||
}
|
||||
|
||||
private volatile static CityListLoader instance;
|
||||
|
||||
private CityListLoader() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 单例模式
|
||||
* @return
|
||||
*/
|
||||
public static CityListLoader getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (CityListLoader.class) {
|
||||
if (instance == null) {
|
||||
instance = new CityListLoader();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析357个城市数据
|
||||
* @param context
|
||||
*/
|
||||
public void loadCityData(Context context) {
|
||||
|
||||
String cityJson = utils.getJson(context, Constant.CITY_DATA);
|
||||
Type type = new TypeToken<ArrayList<CityInfoBean>>() {
|
||||
}.getType();
|
||||
|
||||
//解析省份
|
||||
ArrayList<CityInfoBean> mProvinceBeanArrayList = new Gson().fromJson(cityJson, type);
|
||||
if (mProvinceBeanArrayList == null || mProvinceBeanArrayList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int p = 0; p < mProvinceBeanArrayList.size(); p++) {
|
||||
|
||||
//遍历每个省份
|
||||
CityInfoBean itemProvince = mProvinceBeanArrayList.get(p);
|
||||
|
||||
//每个省份对应下面的市
|
||||
ArrayList<CityInfoBean> cityList = itemProvince.getCityList();
|
||||
|
||||
//遍历当前省份下面城市的所有数据
|
||||
for (int j = 0; j < cityList.size(); j++) {
|
||||
mCityListData.add(cityList.get(j));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析34个省市直辖区数据
|
||||
* @param context
|
||||
*/
|
||||
public void loadProData(Context context) {
|
||||
String cityJson = utils.getJson(context, Constant.CITY_DATA);
|
||||
Type type = new TypeToken<ArrayList<CityInfoBean>>() {
|
||||
}.getType();
|
||||
|
||||
//解析省份
|
||||
mProListData = new Gson().fromJson(cityJson, type);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citylist.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
/**
|
||||
* 说明:
|
||||
* 作者: fangkaijin on 2017/4/10.13:27
|
||||
* 邮箱:fangkaijin@gmail.com
|
||||
*/
|
||||
|
||||
public class CleanableEditView extends EditText implements TextWatcher, View.OnFocusChangeListener {
|
||||
/**
|
||||
* 左右两侧图片资源
|
||||
*/
|
||||
private Drawable left, right;
|
||||
/**
|
||||
* 是否获取焦点,默认没有焦点
|
||||
*/
|
||||
private boolean hasFocus = false;
|
||||
/**
|
||||
* 手指抬起时的X坐标
|
||||
*/
|
||||
private int xUp = 0;
|
||||
|
||||
public CleanableEditView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CleanableEditView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.editTextStyle);
|
||||
}
|
||||
|
||||
public CleanableEditView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initWedgits(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化各组件
|
||||
* @param attrs
|
||||
* 属性集
|
||||
*/
|
||||
private void initWedgits(AttributeSet attrs) {
|
||||
try {
|
||||
left = getCompoundDrawables()[0];
|
||||
right = getCompoundDrawables()[2];
|
||||
initDatas();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
private void initDatas() {
|
||||
try {
|
||||
// 第一次显示,隐藏删除图标
|
||||
setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);
|
||||
addListeners();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加事件监听
|
||||
*/
|
||||
private void addListeners() {
|
||||
try {
|
||||
setOnFocusChangeListener(this);
|
||||
addTextChangedListener(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count,
|
||||
int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int after) {
|
||||
if (hasFocus) {
|
||||
if (TextUtils.isEmpty(s)) {
|
||||
// 如果为空,则不显示删除图标
|
||||
setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);
|
||||
} else {
|
||||
// 如果非空,则要显示删除图标
|
||||
if (null == right) {
|
||||
right = getCompoundDrawables()[2];
|
||||
}
|
||||
setCompoundDrawablesWithIntrinsicBounds(left, null, right, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
try {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_UP:
|
||||
// 获取点击时手指抬起的X坐标
|
||||
xUp = (int) event.getX();
|
||||
// 当点击的坐标到当前输入框右侧的距离小于等于getCompoundPaddingRight()的距离时,则认为是点击了删除图标
|
||||
// getCompoundPaddingRight()的说明:Returns the right padding of the view, plus space for the right Drawable if any.
|
||||
if ((getWidth() - xUp) <= getCompoundPaddingRight()) {
|
||||
if (!TextUtils.isEmpty(getText().toString())) {
|
||||
setText("");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
try {
|
||||
this.hasFocus = hasFocus;
|
||||
String msg=getText().toString();
|
||||
|
||||
if(hasFocus){
|
||||
if(msg.equalsIgnoreCase("")){
|
||||
setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);
|
||||
}else{
|
||||
setCompoundDrawablesWithIntrinsicBounds(left, null, right, null);
|
||||
}
|
||||
}
|
||||
if(hasFocus==false){
|
||||
setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//获取输入内容
|
||||
public String text_String (){
|
||||
return getText().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
package com.lljjcoder.style.citypickerview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.lljjcoder.Interface.OnCityItemClickListener;
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
import com.lljjcoder.citywheel.CityConfig;
|
||||
import com.lljjcoder.citywheel.CityParseHelper;
|
||||
import com.lljjcoder.style.citylist.Toast.ToastUtils;
|
||||
import com.lljjcoder.style.citypickerview.widget.CanShow;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.OnWheelChangedListener;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.WheelView;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.adapters.ArrayWheelAdapter;
|
||||
import com.lljjcoder.utils.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 省市区三级选择
|
||||
* 作者:liji on 2015/12/17 10:40
|
||||
* 邮箱:lijiwork@sina.com
|
||||
*/
|
||||
public class CityPickerView implements CanShow, OnWheelChangedListener {
|
||||
|
||||
private String TAG = "citypicker_log";
|
||||
|
||||
private PopupWindow popwindow;
|
||||
|
||||
private View popview;
|
||||
|
||||
private WheelView mViewProvince;
|
||||
|
||||
private WheelView mViewCity;
|
||||
|
||||
private WheelView mViewDistrict;
|
||||
|
||||
private RelativeLayout mRelativeTitleBg;
|
||||
|
||||
private TextView mTvOK;
|
||||
|
||||
private TextView mTvTitle;
|
||||
|
||||
private TextView mTvCancel;
|
||||
|
||||
private OnCityItemClickListener mBaseListener;
|
||||
|
||||
private CityParseHelper parseHelper;
|
||||
|
||||
private CityConfig config;
|
||||
|
||||
private Context context;
|
||||
|
||||
private List<ProvinceBean> proArra;
|
||||
|
||||
public void setOnCityItemClickListener(OnCityItemClickListener listener) {
|
||||
mBaseListener = listener;
|
||||
}
|
||||
|
||||
public CityPickerView() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置属性
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
public void setConfig(final CityConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化,默认解析城市数据,提交加载速度
|
||||
*/
|
||||
public void init(Context context) {
|
||||
this.context = context;
|
||||
parseHelper = new CityParseHelper();
|
||||
|
||||
//解析初始数据
|
||||
if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
|
||||
parseHelper.initData(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化popWindow
|
||||
*/
|
||||
private void initCityPickerPopwindow() {
|
||||
|
||||
if (config == null) {
|
||||
throw new IllegalArgumentException("please set config first...");
|
||||
}
|
||||
|
||||
//解析初始数据
|
||||
if (parseHelper == null) {
|
||||
parseHelper = new CityParseHelper();
|
||||
}
|
||||
|
||||
if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
|
||||
ToastUtils.showLongToast(context, "请在Activity中增加init操作");
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(context);
|
||||
popview = layoutInflater.inflate(R.layout.pop_citypicker, null);
|
||||
|
||||
mViewProvince = (WheelView) popview.findViewById(R.id.id_province);
|
||||
mViewCity = (WheelView) popview.findViewById(R.id.id_city);
|
||||
mViewDistrict = (WheelView) popview.findViewById(R.id.id_district);
|
||||
mRelativeTitleBg = (RelativeLayout) popview.findViewById(R.id.rl_title);
|
||||
mTvOK = (TextView) popview.findViewById(R.id.tv_confirm);
|
||||
mTvTitle = (TextView) popview.findViewById(R.id.tv_title);
|
||||
mTvCancel = (TextView) popview.findViewById(R.id.tv_cancel);
|
||||
|
||||
popwindow = new PopupWindow(popview, LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
popwindow.setAnimationStyle(R.style.AnimBottom);
|
||||
popwindow.setBackgroundDrawable(new ColorDrawable());
|
||||
popwindow.setTouchable(true);
|
||||
popwindow.setOutsideTouchable(false);
|
||||
popwindow.setFocusable(true);
|
||||
|
||||
popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
if (config.isShowBackground()) {
|
||||
utils.setBackgroundAlpha(context, 1.0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 设置标题背景颜色
|
||||
*/
|
||||
if (!TextUtils.isEmpty(config.getTitleBackgroundColorStr())) {
|
||||
if (config.getTitleBackgroundColorStr().startsWith("#")) {
|
||||
mRelativeTitleBg.setBackgroundColor(Color.parseColor(config.getTitleBackgroundColorStr()));
|
||||
} else {
|
||||
mRelativeTitleBg.setBackgroundColor(Color.parseColor("#" + config.getTitleBackgroundColorStr()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//标题
|
||||
if (!TextUtils.isEmpty(config.getTitle())) {
|
||||
mTvTitle.setText(config.getTitle());
|
||||
}
|
||||
|
||||
//标题文字大小
|
||||
if (config.getTitleTextSize() > 0) {
|
||||
mTvTitle.setTextSize(config.getTitleTextSize());
|
||||
}
|
||||
|
||||
//标题文字颜色
|
||||
if (!TextUtils.isEmpty(config.getTitleTextColorStr())) {
|
||||
if (config.getTitleTextColorStr().startsWith("#")) {
|
||||
mTvTitle.setTextColor(Color.parseColor(config.getTitleTextColorStr()));
|
||||
} else {
|
||||
mTvTitle.setTextColor(Color.parseColor("#" + config.getTitleTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
//设置确认按钮文字大小颜色
|
||||
if (!TextUtils.isEmpty(config.getConfirmTextColorStr())) {
|
||||
if (config.getConfirmTextColorStr().startsWith("#")) {
|
||||
mTvOK.setTextColor(Color.parseColor(config.getConfirmTextColorStr()));
|
||||
} else {
|
||||
mTvOK.setTextColor(Color.parseColor("#" + config.getConfirmTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(config.getConfirmText())) {
|
||||
mTvOK.setText(config.getConfirmText());
|
||||
}
|
||||
|
||||
if ((config.getConfirmTextSize() > 0)) {
|
||||
mTvOK.setTextSize(config.getConfirmTextSize());
|
||||
}
|
||||
|
||||
//设置取消按钮文字颜色
|
||||
if (!TextUtils.isEmpty(config.getCancelTextColorStr())) {
|
||||
if (config.getCancelTextColorStr().startsWith("#")) {
|
||||
mTvCancel.setTextColor(Color.parseColor(config.getCancelTextColorStr()));
|
||||
} else {
|
||||
mTvCancel.setTextColor(Color.parseColor("#" + config.getCancelTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(config.getCancelText())) {
|
||||
mTvCancel.setText(config.getCancelText());
|
||||
}
|
||||
|
||||
if ((config.getCancelTextSize() > 0)) {
|
||||
mTvCancel.setTextSize(config.getCancelTextSize());
|
||||
}
|
||||
|
||||
//只显示省市两级联动
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO) {
|
||||
mViewCity.setVisibility(View.GONE);
|
||||
mViewDistrict.setVisibility(View.GONE);
|
||||
} else if (config.getWheelType() == CityConfig.WheelType.PRO_CITY) {
|
||||
mViewDistrict.setVisibility(View.GONE);
|
||||
} else {
|
||||
mViewProvince.setVisibility(View.VISIBLE);
|
||||
mViewCity.setVisibility(View.VISIBLE);
|
||||
mViewDistrict.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
// 添加change事件
|
||||
mViewProvince.addChangingListener(this);
|
||||
// 添加change事件
|
||||
mViewCity.addChangingListener(this);
|
||||
// 添加change事件
|
||||
mViewDistrict.addChangingListener(this);
|
||||
// 添加onclick事件
|
||||
mTvCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mBaseListener.onCancel();
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
//确认选择
|
||||
mTvOK.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (parseHelper != null) {
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO) {
|
||||
mBaseListener.onSelected(parseHelper.getProvinceBean(), new CityBean(), new DistrictBean());
|
||||
} else if (config.getWheelType() == CityConfig.WheelType.PRO_CITY) {
|
||||
mBaseListener.onSelected(parseHelper.getProvinceBean(),
|
||||
parseHelper.getCityBean(),
|
||||
new DistrictBean());
|
||||
} else {
|
||||
mBaseListener.onSelected(parseHelper.getProvinceBean(),
|
||||
parseHelper.getCityBean(),
|
||||
parseHelper.getDistrictBean());
|
||||
}
|
||||
|
||||
} else {
|
||||
mBaseListener.onSelected(new ProvinceBean(), new CityBean(), new DistrictBean());
|
||||
}
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
//显示省市区数据
|
||||
setUpData();
|
||||
|
||||
//背景半透明
|
||||
if (config != null && config.isShowBackground()) {
|
||||
utils.setBackgroundAlpha(context, 0.5f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据是否显示港澳台数据来初始化最新的数据
|
||||
*
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
private List<ProvinceBean> getProArrData(List<ProvinceBean> array) {
|
||||
|
||||
List<ProvinceBean> provinceBeanList = new ArrayList<>();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
provinceBeanList.add(array.get(i));
|
||||
}
|
||||
|
||||
//不需要港澳台数据
|
||||
if (!config.isShowGAT()) {
|
||||
provinceBeanList.remove(provinceBeanList.size() - 1);
|
||||
provinceBeanList.remove(provinceBeanList.size() - 1);
|
||||
provinceBeanList.remove(provinceBeanList.size() - 1);
|
||||
}
|
||||
|
||||
proArra = new ArrayList<ProvinceBean>();
|
||||
for (int i = 0; i < provinceBeanList.size(); i++) {
|
||||
proArra.add(provinceBeanList.get(i));
|
||||
}
|
||||
|
||||
return proArra;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载数据
|
||||
*/
|
||||
private void setUpData() {
|
||||
|
||||
if (parseHelper == null || config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//根据是否显示港澳台数据来初始化最新的数据
|
||||
getProArrData(parseHelper.getProvinceBeenArray());
|
||||
|
||||
int provinceDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultProvinceName()) && proArra.size() > 0) {
|
||||
for (int i = 0; i < proArra.size(); i++) {
|
||||
if (proArra.get(i).getName().equals(config.getDefaultProvinceName())) {
|
||||
provinceDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter arrayWheelAdapter = new ArrayWheelAdapter<ProvinceBean>(context, proArra);
|
||||
mViewProvince.setViewAdapter(arrayWheelAdapter);
|
||||
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE && config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
arrayWheelAdapter.setItemResource(config.getCustomItemLayout());
|
||||
arrayWheelAdapter.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
arrayWheelAdapter.setItemResource(R.layout.default_item_city);
|
||||
arrayWheelAdapter.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
//获取所设置的省的位置,直接定位到该位置
|
||||
if (-1 != provinceDefault) {
|
||||
mViewProvince.setCurrentItem(provinceDefault);
|
||||
}
|
||||
|
||||
// 设置可见条目数量
|
||||
mViewProvince.setVisibleItems(config.getVisibleItems());
|
||||
mViewCity.setVisibleItems(config.getVisibleItems());
|
||||
mViewDistrict.setVisibleItems(config.getVisibleItems());
|
||||
mViewProvince.setCyclic(config.isProvinceCyclic());
|
||||
mViewCity.setCyclic(config.isCityCyclic());
|
||||
mViewDistrict.setCyclic(config.isDistrictCyclic());
|
||||
|
||||
//显示滚轮模糊效果
|
||||
mViewProvince.setDrawShadows(config.isDrawShadows());
|
||||
mViewCity.setDrawShadows(config.isDrawShadows());
|
||||
mViewDistrict.setDrawShadows(config.isDrawShadows());
|
||||
|
||||
//中间线的颜色及高度
|
||||
mViewProvince.setLineColorStr(config.getLineColor());
|
||||
mViewProvince.setLineWidth(config.getLineHeigh());
|
||||
mViewCity.setLineColorStr(config.getLineColor());
|
||||
mViewCity.setLineWidth(config.getLineHeigh());
|
||||
mViewDistrict.setLineColorStr(config.getLineColor());
|
||||
mViewDistrict.setLineWidth(config.getLineHeigh());
|
||||
|
||||
updateCities();
|
||||
|
||||
updateAreas();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前的省,更新市WheelView的信息
|
||||
*/
|
||||
private void updateCities() {
|
||||
|
||||
if (parseHelper == null || config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//省份滚轮滑动的当前位置
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
|
||||
//省份选中的名称
|
||||
ProvinceBean mProvinceBean = proArra.get(pCurrent);
|
||||
parseHelper.setProvinceBean(mProvinceBean);
|
||||
|
||||
if (parseHelper.getPro_CityMap() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<CityBean> cities = parseHelper.getPro_CityMap().get(mProvinceBean.getName());
|
||||
if (cities == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//设置最初的默认城市
|
||||
int cityDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultCityName()) && cities.size() > 0) {
|
||||
for (int i = 0; i < cities.size(); i++) {
|
||||
if (config.getDefaultCityName().equals(cities.get(i).getName())) {
|
||||
cityDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter cityWheel = new ArrayWheelAdapter<CityBean>(context, cities);
|
||||
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE && config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
cityWheel.setItemResource(config.getCustomItemLayout());
|
||||
cityWheel.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
cityWheel.setItemResource(R.layout.default_item_city);
|
||||
cityWheel.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
mViewCity.setViewAdapter(cityWheel);
|
||||
if (-1 != cityDefault) {
|
||||
mViewCity.setCurrentItem(cityDefault);
|
||||
} else {
|
||||
mViewCity.setCurrentItem(0);
|
||||
}
|
||||
updateAreas();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前的市,更新区WheelView的信息
|
||||
*/
|
||||
private void updateAreas() {
|
||||
|
||||
int pCurrent = mViewCity.getCurrentItem();
|
||||
if (parseHelper.getPro_CityMap() == null || parseHelper.getCity_DisMap() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO_CITY
|
||||
|| config.getWheelType() == CityConfig.WheelType.PRO_CITY_DIS) {
|
||||
|
||||
CityBean mCityBean = parseHelper.getPro_CityMap().get(parseHelper.getProvinceBean().getName()).get(pCurrent);
|
||||
parseHelper.setCityBean(mCityBean);
|
||||
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO_CITY_DIS) {
|
||||
|
||||
List<DistrictBean> areas = parseHelper.getCity_DisMap()
|
||||
.get(parseHelper.getProvinceBean().getName() + mCityBean.getName());
|
||||
|
||||
if (areas == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int districtDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultDistrict()) && areas.size() > 0) {
|
||||
for (int i = 0; i < areas.size(); i++) {
|
||||
if (config.getDefaultDistrict().equals(areas.get(i).getName())) {
|
||||
districtDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter districtWheel = new ArrayWheelAdapter<DistrictBean>(context, areas);
|
||||
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE
|
||||
&& config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
districtWheel.setItemResource(config.getCustomItemLayout());
|
||||
districtWheel.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
districtWheel.setItemResource(R.layout.default_item_city);
|
||||
districtWheel.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
mViewDistrict.setViewAdapter(districtWheel);
|
||||
|
||||
DistrictBean mDistrictBean = null;
|
||||
if (parseHelper.getDisMap() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (-1 != districtDefault) {
|
||||
mViewDistrict.setCurrentItem(districtDefault);
|
||||
//获取第一个区名称
|
||||
mDistrictBean = parseHelper.getDisMap().get(parseHelper.getProvinceBean().getName()
|
||||
+ mCityBean.getName() + config.getDefaultDistrict());
|
||||
} else {
|
||||
mViewDistrict.setCurrentItem(0);
|
||||
if (areas.size() > 0) {
|
||||
mDistrictBean = areas.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
parseHelper.setDistrictBean(mDistrictBean);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showCityPicker() {
|
||||
initCityPickerPopwindow();
|
||||
if (!isShow()) {
|
||||
popwindow.showAtLocation(popview, Gravity.BOTTOM, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
if (isShow()) {
|
||||
popwindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShow() {
|
||||
return popwindow.isShowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(WheelView wheel, int oldValue, int newValue) {
|
||||
if (wheel == mViewProvince) {
|
||||
updateCities();
|
||||
} else if (wheel == mViewCity) {
|
||||
updateAreas();
|
||||
} else if (wheel == mViewDistrict) {
|
||||
if (parseHelper != null && parseHelper.getCity_DisMap() != null) {
|
||||
|
||||
DistrictBean mDistrictBean = parseHelper.getCity_DisMap()
|
||||
.get(parseHelper.getProvinceBean().getName() + parseHelper.getCityBean().getName()).get(newValue);
|
||||
|
||||
parseHelper.setDistrictBean(mDistrictBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
package com.lljjcoder.style.citypickerview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.lljjcoder.Interface.OnCityItemClickListener;
|
||||
import com.lljjcoder.bean.CityBean;
|
||||
import com.lljjcoder.bean.DistrictBean;
|
||||
import com.lljjcoder.bean.ProvinceBean;
|
||||
import com.lljjcoder.citywheel.CityConfig;
|
||||
import com.lljjcoder.citywheel.CityParseHelper;
|
||||
import com.lljjcoder.style.citylist.Toast.ToastUtils;
|
||||
import com.lljjcoder.style.citypickerview.widget.CanShow;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.OnWheelChangedListener;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.WheelView;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.adapters.ArrayWheelAdapter;
|
||||
import com.lljjcoder.utils.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 省市区三级选择
|
||||
* 作者:liji on 2015/12/17 10:40
|
||||
* 邮箱:lijiwork@sina.com
|
||||
*/
|
||||
public class CityPickerViewTw implements CanShow, OnWheelChangedListener {
|
||||
|
||||
private String TAG = "citypicker_log";
|
||||
|
||||
private PopupWindow popwindow;
|
||||
|
||||
private View popview;
|
||||
|
||||
private WheelView mViewProvince;
|
||||
|
||||
private WheelView mViewCity;
|
||||
|
||||
private WheelView mViewDistrict;
|
||||
|
||||
private RelativeLayout mRelativeTitleBg;
|
||||
|
||||
private TextView mTvOK;
|
||||
|
||||
private TextView mTvTitle;
|
||||
|
||||
private TextView mTvCancel;
|
||||
|
||||
private OnCityItemClickListener mBaseListener;
|
||||
|
||||
private CityParseHelper parseHelper;
|
||||
|
||||
private CityConfig config;
|
||||
|
||||
private Context context;
|
||||
|
||||
private List<ProvinceBean> proArra;
|
||||
|
||||
public void setOnCityItemClickListener(OnCityItemClickListener listener) {
|
||||
mBaseListener = listener;
|
||||
}
|
||||
|
||||
public CityPickerViewTw() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置属性
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
public void setConfig(final CityConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化,默认解析城市数据,提交加载速度
|
||||
*/
|
||||
public void init(Context context) {
|
||||
this.context = context;
|
||||
parseHelper = new CityParseHelper();
|
||||
|
||||
//解析初始数据
|
||||
if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
|
||||
parseHelper.initDataTw(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化popWindow
|
||||
*/
|
||||
private void initCityPickerPopwindow() {
|
||||
|
||||
if (config == null) {
|
||||
throw new IllegalArgumentException("please set config first...");
|
||||
}
|
||||
|
||||
//解析初始数据
|
||||
if (parseHelper == null) {
|
||||
parseHelper = new CityParseHelper();
|
||||
}
|
||||
|
||||
if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
|
||||
ToastUtils.showLongToast(context, "请在Activity中增加init操作");
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutInflater layoutInflater = LayoutInflater.from(context);
|
||||
popview = layoutInflater.inflate(R.layout.pop_citypicker, null);
|
||||
|
||||
mViewProvince = (WheelView) popview.findViewById(R.id.id_province);
|
||||
mViewCity = (WheelView) popview.findViewById(R.id.id_city);
|
||||
mViewDistrict = (WheelView) popview.findViewById(R.id.id_district);
|
||||
mRelativeTitleBg = (RelativeLayout) popview.findViewById(R.id.rl_title);
|
||||
mTvOK = (TextView) popview.findViewById(R.id.tv_confirm);
|
||||
mTvTitle = (TextView) popview.findViewById(R.id.tv_title);
|
||||
mTvCancel = (TextView) popview.findViewById(R.id.tv_cancel);
|
||||
|
||||
popwindow = new PopupWindow(popview, LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
popwindow.setAnimationStyle(R.style.AnimBottom);
|
||||
popwindow.setBackgroundDrawable(new ColorDrawable());
|
||||
popwindow.setTouchable(true);
|
||||
popwindow.setOutsideTouchable(false);
|
||||
popwindow.setFocusable(true);
|
||||
|
||||
popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss() {
|
||||
if (config.isShowBackground()) {
|
||||
utils.setBackgroundAlpha(context, 1.0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 设置标题背景颜色
|
||||
*/
|
||||
if (!TextUtils.isEmpty(config.getTitleBackgroundColorStr())) {
|
||||
if (config.getTitleBackgroundColorStr().startsWith("#")) {
|
||||
mRelativeTitleBg.setBackgroundColor(Color.parseColor(config.getTitleBackgroundColorStr()));
|
||||
} else {
|
||||
mRelativeTitleBg.setBackgroundColor(Color.parseColor("#" + config.getTitleBackgroundColorStr()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//标题
|
||||
if (!TextUtils.isEmpty(config.getTitle())) {
|
||||
mTvTitle.setText(config.getTitle());
|
||||
}
|
||||
|
||||
//标题文字大小
|
||||
if (config.getTitleTextSize() > 0) {
|
||||
mTvTitle.setTextSize(config.getTitleTextSize());
|
||||
}
|
||||
|
||||
//标题文字颜色
|
||||
if (!TextUtils.isEmpty(config.getTitleTextColorStr())) {
|
||||
if (config.getTitleTextColorStr().startsWith("#")) {
|
||||
mTvTitle.setTextColor(Color.parseColor(config.getTitleTextColorStr()));
|
||||
} else {
|
||||
mTvTitle.setTextColor(Color.parseColor("#" + config.getTitleTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
//设置确认按钮文字大小颜色
|
||||
if (!TextUtils.isEmpty(config.getConfirmTextColorStr())) {
|
||||
if (config.getConfirmTextColorStr().startsWith("#")) {
|
||||
mTvOK.setTextColor(Color.parseColor(config.getConfirmTextColorStr()));
|
||||
} else {
|
||||
mTvOK.setTextColor(Color.parseColor("#" + config.getConfirmTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(config.getConfirmText())) {
|
||||
mTvOK.setText(config.getConfirmText());
|
||||
}
|
||||
|
||||
if ((config.getConfirmTextSize() > 0)) {
|
||||
mTvOK.setTextSize(config.getConfirmTextSize());
|
||||
}
|
||||
|
||||
//设置取消按钮文字颜色
|
||||
if (!TextUtils.isEmpty(config.getCancelTextColorStr())) {
|
||||
if (config.getCancelTextColorStr().startsWith("#")) {
|
||||
mTvCancel.setTextColor(Color.parseColor(config.getCancelTextColorStr()));
|
||||
} else {
|
||||
mTvCancel.setTextColor(Color.parseColor("#" + config.getCancelTextColorStr()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(config.getCancelText())) {
|
||||
mTvCancel.setText(config.getCancelText());
|
||||
}
|
||||
|
||||
if ((config.getCancelTextSize() > 0)) {
|
||||
mTvCancel.setTextSize(config.getCancelTextSize());
|
||||
}
|
||||
|
||||
//只显示省市两级联动
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO) {
|
||||
mViewCity.setVisibility(View.GONE);
|
||||
mViewDistrict.setVisibility(View.GONE);
|
||||
} else if (config.getWheelType() == CityConfig.WheelType.PRO_CITY) {
|
||||
mViewDistrict.setVisibility(View.GONE);
|
||||
} else {
|
||||
mViewProvince.setVisibility(View.VISIBLE);
|
||||
mViewCity.setVisibility(View.VISIBLE);
|
||||
mViewDistrict.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
// 添加change事件
|
||||
mViewProvince.addChangingListener(this);
|
||||
// 添加change事件
|
||||
mViewCity.addChangingListener(this);
|
||||
// 添加change事件
|
||||
mViewDistrict.addChangingListener(this);
|
||||
// 添加onclick事件
|
||||
mTvCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mBaseListener.onCancel();
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
//确认选择
|
||||
mTvOK.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (parseHelper != null) {
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO) {
|
||||
mBaseListener.onSelected(parseHelper.getProvinceBean(), new CityBean(), new DistrictBean());
|
||||
} else if (config.getWheelType() == CityConfig.WheelType.PRO_CITY) {
|
||||
mBaseListener.onSelected(parseHelper.getProvinceBean(),
|
||||
parseHelper.getCityBean(),
|
||||
new DistrictBean());
|
||||
} else {
|
||||
mBaseListener.onSelected(parseHelper.getProvinceBean(),
|
||||
parseHelper.getCityBean(),
|
||||
parseHelper.getDistrictBean());
|
||||
}
|
||||
|
||||
} else {
|
||||
mBaseListener.onSelected(new ProvinceBean(), new CityBean(), new DistrictBean());
|
||||
}
|
||||
hide();
|
||||
}
|
||||
});
|
||||
|
||||
//显示省市区数据
|
||||
setUpData();
|
||||
|
||||
//背景半透明
|
||||
if (config != null && config.isShowBackground()) {
|
||||
utils.setBackgroundAlpha(context, 0.5f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据是否显示港澳台数据来初始化最新的数据
|
||||
*
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
private List<ProvinceBean> getProArrData(List<ProvinceBean> array) {
|
||||
|
||||
List<ProvinceBean> provinceBeanList = new ArrayList<>();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
provinceBeanList.add(array.get(i));
|
||||
}
|
||||
|
||||
//不需要港澳台数据
|
||||
if (!config.isShowGAT()) {
|
||||
provinceBeanList.remove(provinceBeanList.size() - 1);
|
||||
provinceBeanList.remove(provinceBeanList.size() - 1);
|
||||
provinceBeanList.remove(provinceBeanList.size() - 1);
|
||||
}
|
||||
|
||||
proArra = new ArrayList<ProvinceBean>();
|
||||
for (int i = 0; i < provinceBeanList.size(); i++) {
|
||||
proArra.add(provinceBeanList.get(i));
|
||||
}
|
||||
|
||||
return proArra;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载数据
|
||||
*/
|
||||
private void setUpData() {
|
||||
|
||||
if (parseHelper == null || config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//根据是否显示港澳台数据来初始化最新的数据
|
||||
getProArrData(parseHelper.getProvinceBeenArray());
|
||||
|
||||
int provinceDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultProvinceName()) && proArra.size() > 0) {
|
||||
for (int i = 0; i < proArra.size(); i++) {
|
||||
if (proArra.get(i).getName().equals(config.getDefaultProvinceName())) {
|
||||
provinceDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter arrayWheelAdapter = new ArrayWheelAdapter<ProvinceBean>(context, proArra);
|
||||
mViewProvince.setViewAdapter(arrayWheelAdapter);
|
||||
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE && config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
arrayWheelAdapter.setItemResource(config.getCustomItemLayout());
|
||||
arrayWheelAdapter.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
arrayWheelAdapter.setItemResource(R.layout.default_item_city);
|
||||
arrayWheelAdapter.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
//获取所设置的省的位置,直接定位到该位置
|
||||
if (-1 != provinceDefault) {
|
||||
mViewProvince.setCurrentItem(provinceDefault);
|
||||
}
|
||||
|
||||
// 设置可见条目数量
|
||||
mViewProvince.setVisibleItems(config.getVisibleItems());
|
||||
mViewCity.setVisibleItems(config.getVisibleItems());
|
||||
mViewDistrict.setVisibleItems(config.getVisibleItems());
|
||||
mViewProvince.setCyclic(config.isProvinceCyclic());
|
||||
mViewCity.setCyclic(config.isCityCyclic());
|
||||
mViewDistrict.setCyclic(config.isDistrictCyclic());
|
||||
|
||||
//显示滚轮模糊效果
|
||||
mViewProvince.setDrawShadows(config.isDrawShadows());
|
||||
mViewCity.setDrawShadows(config.isDrawShadows());
|
||||
mViewDistrict.setDrawShadows(config.isDrawShadows());
|
||||
|
||||
//中间线的颜色及高度
|
||||
mViewProvince.setLineColorStr(config.getLineColor());
|
||||
mViewProvince.setLineWidth(config.getLineHeigh());
|
||||
mViewCity.setLineColorStr(config.getLineColor());
|
||||
mViewCity.setLineWidth(config.getLineHeigh());
|
||||
mViewDistrict.setLineColorStr(config.getLineColor());
|
||||
mViewDistrict.setLineWidth(config.getLineHeigh());
|
||||
|
||||
updateCities();
|
||||
|
||||
updateAreas();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前的省,更新市WheelView的信息
|
||||
*/
|
||||
private void updateCities() {
|
||||
|
||||
if (parseHelper == null || config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//省份滚轮滑动的当前位置
|
||||
int pCurrent = mViewProvince.getCurrentItem();
|
||||
|
||||
//省份选中的名称
|
||||
ProvinceBean mProvinceBean = proArra.get(pCurrent);
|
||||
parseHelper.setProvinceBean(mProvinceBean);
|
||||
|
||||
if (parseHelper.getPro_CityMap() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<CityBean> cities = parseHelper.getPro_CityMap().get(mProvinceBean.getName());
|
||||
if (cities == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//设置最初的默认城市
|
||||
int cityDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultCityName()) && cities.size() > 0) {
|
||||
for (int i = 0; i < cities.size(); i++) {
|
||||
if (config.getDefaultCityName().equals(cities.get(i).getName())) {
|
||||
cityDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter cityWheel = new ArrayWheelAdapter<CityBean>(context, cities);
|
||||
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE && config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
cityWheel.setItemResource(config.getCustomItemLayout());
|
||||
cityWheel.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
cityWheel.setItemResource(R.layout.default_item_city);
|
||||
cityWheel.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
mViewCity.setViewAdapter(cityWheel);
|
||||
if (-1 != cityDefault) {
|
||||
mViewCity.setCurrentItem(cityDefault);
|
||||
} else {
|
||||
mViewCity.setCurrentItem(0);
|
||||
}
|
||||
updateAreas();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前的市,更新区WheelView的信息
|
||||
*/
|
||||
private void updateAreas() {
|
||||
|
||||
int pCurrent = mViewCity.getCurrentItem();
|
||||
if (parseHelper.getPro_CityMap() == null || parseHelper.getCity_DisMap() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO_CITY
|
||||
|| config.getWheelType() == CityConfig.WheelType.PRO_CITY_DIS) {
|
||||
|
||||
CityBean mCityBean = parseHelper.getPro_CityMap().get(parseHelper.getProvinceBean().getName()).get(pCurrent);
|
||||
parseHelper.setCityBean(mCityBean);
|
||||
|
||||
if (config.getWheelType() == CityConfig.WheelType.PRO_CITY_DIS) {
|
||||
|
||||
List<DistrictBean> areas = parseHelper.getCity_DisMap()
|
||||
.get(parseHelper.getProvinceBean().getName() + mCityBean.getName());
|
||||
|
||||
if (areas == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int districtDefault = -1;
|
||||
if (!TextUtils.isEmpty(config.getDefaultDistrict()) && areas.size() > 0) {
|
||||
for (int i = 0; i < areas.size(); i++) {
|
||||
if (config.getDefaultDistrict().equals(areas.get(i).getName())) {
|
||||
districtDefault = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayWheelAdapter districtWheel = new ArrayWheelAdapter<DistrictBean>(context, areas);
|
||||
|
||||
//自定义item
|
||||
if (config.getCustomItemLayout() != CityConfig.NONE
|
||||
&& config.getCustomItemTextViewId() != CityConfig.NONE) {
|
||||
districtWheel.setItemResource(config.getCustomItemLayout());
|
||||
districtWheel.setItemTextResource(config.getCustomItemTextViewId());
|
||||
} else {
|
||||
districtWheel.setItemResource(R.layout.default_item_city);
|
||||
districtWheel.setItemTextResource(R.id.default_item_city_name_tv);
|
||||
}
|
||||
|
||||
mViewDistrict.setViewAdapter(districtWheel);
|
||||
|
||||
DistrictBean mDistrictBean = null;
|
||||
if (parseHelper.getDisMap() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (-1 != districtDefault) {
|
||||
mViewDistrict.setCurrentItem(districtDefault);
|
||||
//获取第一个区名称
|
||||
mDistrictBean = parseHelper.getDisMap().get(parseHelper.getProvinceBean().getName()
|
||||
+ mCityBean.getName() + config.getDefaultDistrict());
|
||||
} else {
|
||||
mViewDistrict.setCurrentItem(0);
|
||||
if (areas.size() > 0) {
|
||||
mDistrictBean = areas.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
parseHelper.setDistrictBean(mDistrictBean);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showCityPicker() {
|
||||
initCityPickerPopwindow();
|
||||
if (!isShow()) {
|
||||
popwindow.showAtLocation(popview, Gravity.BOTTOM, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
if (isShow()) {
|
||||
popwindow.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShow() {
|
||||
return popwindow.isShowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(WheelView wheel, int oldValue, int newValue) {
|
||||
if (wheel == mViewProvince) {
|
||||
updateCities();
|
||||
} else if (wheel == mViewCity) {
|
||||
updateAreas();
|
||||
} else if (wheel == mViewDistrict) {
|
||||
if (parseHelper != null && parseHelper.getCity_DisMap() != null) {
|
||||
|
||||
DistrictBean mDistrictBean = parseHelper.getCity_DisMap()
|
||||
.get(parseHelper.getProvinceBean().getName() + parseHelper.getCityBean().getName()).get(newValue);
|
||||
|
||||
parseHelper.setDistrictBean(mDistrictBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.lljjcoder.style.citypickerview.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CityModel {
|
||||
private String name;
|
||||
private List<DistrictModel> districtList;
|
||||
|
||||
public CityModel() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CityModel(String name, List<DistrictModel> districtList) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.districtList = districtList;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<DistrictModel> getDistrictList() {
|
||||
return districtList;
|
||||
}
|
||||
|
||||
public void setDistrictList(List<DistrictModel> districtList) {
|
||||
this.districtList = districtList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CityModel [name=" + name + ", districtList=" + districtList
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.lljjcoder.style.citypickerview.model;
|
||||
|
||||
public class DistrictModel {
|
||||
private String name;
|
||||
private String zipcode;
|
||||
|
||||
public DistrictModel() {
|
||||
super();
|
||||
}
|
||||
|
||||
public DistrictModel(String name, String zipcode) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.zipcode = zipcode;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getZipcode() {
|
||||
return zipcode;
|
||||
}
|
||||
|
||||
public void setZipcode(String zipcode) {
|
||||
this.zipcode = zipcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DistrictModel [name=" + name + ", zipcode=" + zipcode + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.lljjcoder.style.citypickerview.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ProvinceModel {
|
||||
private String name;
|
||||
private List<CityModel> cityList;
|
||||
|
||||
public ProvinceModel() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ProvinceModel(String name, List<CityModel> cityList) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.cityList = cityList;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<CityModel> getCityList() {
|
||||
return cityList;
|
||||
}
|
||||
|
||||
public void setCityList(List<CityModel> cityList) {
|
||||
this.cityList = cityList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProvinceModel [name=" + name + ", cityList=" + cityList + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.lljjcoder.style.citypickerview.widget;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2016/6/30 14:58
|
||||
* 邮箱:lijiwork@sina.com
|
||||
*/
|
||||
public interface CanShow {
|
||||
void hide();
|
||||
|
||||
boolean isShow();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.lljjcoder.style.citypickerview.widget;
|
||||
|
||||
|
||||
public abstract class XCallbackListener {
|
||||
|
||||
protected abstract void callback(Object... obj);
|
||||
|
||||
public void call(Object... obj) {
|
||||
callback(obj);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Android Wheel Control.
|
||||
* https://code.google.com/p/android-wheel/
|
||||
*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
/**
|
||||
* Range for visible items.
|
||||
*/
|
||||
public class ItemsRange {
|
||||
// First item number
|
||||
private int first;
|
||||
|
||||
// Items count
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* Default constructor. Creates an empty range
|
||||
*/
|
||||
public ItemsRange() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param first the number of first item
|
||||
* @param count the count of items
|
||||
*/
|
||||
public ItemsRange(int first, int count) {
|
||||
this.first = first;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of first item
|
||||
* @return the number of the first item
|
||||
*/
|
||||
public int getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of last item
|
||||
* @return the number of last item
|
||||
*/
|
||||
public int getLast() {
|
||||
return getFirst() + getCount() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items count
|
||||
* @return the count of items
|
||||
*/
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether item is contained by range
|
||||
* @param index the item number
|
||||
* @return true if item is contained
|
||||
*/
|
||||
public boolean contains(int index) {
|
||||
return index >= getFirst() && index <= getLast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
/**
|
||||
* Wheel changed listener interface.
|
||||
* <p>The onChanged() method is called whenever current wheel positions is changed:
|
||||
* <li> New Wheel position is set
|
||||
* <li> Wheel view is scrolled
|
||||
*/
|
||||
public interface OnWheelChangedListener {
|
||||
/**
|
||||
* Callback method to be invoked when current item changed
|
||||
* @param wheel the wheel view whose state has changed
|
||||
* @param oldValue the old value of current item
|
||||
* @param newValue the new value of current item
|
||||
*/
|
||||
void onChanged(WheelView wheel, int oldValue, int newValue);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
/**
|
||||
* Wheel clicked listener interface.
|
||||
* <p>The onItemClicked() method is called whenever a wheel item is clicked
|
||||
* <li> New Wheel position is set
|
||||
* <li> Wheel view is scrolled
|
||||
*/
|
||||
public interface OnWheelClickedListener {
|
||||
/**
|
||||
* Callback method to be invoked when current item clicked
|
||||
* @param wheel the wheel view
|
||||
* @param itemIndex the index of clicked item
|
||||
*/
|
||||
void onItemClicked(WheelView wheel, int itemIndex);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
/**
|
||||
* Wheel scrolled listener interface.
|
||||
*/
|
||||
public interface OnWheelScrollListener {
|
||||
/**
|
||||
* Callback method to be invoked when scrolling started.
|
||||
* @param wheel the wheel view whose state has changed.
|
||||
*/
|
||||
void onScrollingStarted(WheelView wheel);
|
||||
|
||||
/**
|
||||
* Callback method to be invoked when scrolling ended.
|
||||
* @param wheel the wheel view whose state has changed.
|
||||
*/
|
||||
void onScrollingFinished(WheelView wheel);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
/**
|
||||
* Wheel adapter interface
|
||||
*
|
||||
* @deprecated Use WheelViewAdapter
|
||||
*/
|
||||
public interface WheelAdapter {
|
||||
/**
|
||||
* Gets items count
|
||||
* @return the count of wheel items
|
||||
*/
|
||||
public int getItemsCount();
|
||||
|
||||
/**
|
||||
* Gets a wheel item by index.
|
||||
*
|
||||
* @param index the item index
|
||||
* @return the wheel item text or null
|
||||
*/
|
||||
public String getItem(int index);
|
||||
|
||||
/**
|
||||
* Gets maximum item length. It is used to determine the wheel width.
|
||||
* If -1 is returned there will be used the default wheel width.
|
||||
*
|
||||
* @return the maximum item length or -1
|
||||
*/
|
||||
public int getMaximumLength();
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Android Wheel Control.
|
||||
* https://code.google.com/p/android-wheel/
|
||||
*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* Recycle stores wheel items to reuse.
|
||||
*/
|
||||
public class WheelRecycle {
|
||||
// Cached items
|
||||
private List<View> items;
|
||||
|
||||
// Cached empty items
|
||||
private List<View> emptyItems;
|
||||
|
||||
// Wheel view
|
||||
private WheelView wheel;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param wheel the wheel view
|
||||
*/
|
||||
public WheelRecycle(WheelView wheel) {
|
||||
this.wheel = wheel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recycles items from specified layout.
|
||||
* There are saved only items not included to specified range.
|
||||
* All the cached items are removed from original layout.
|
||||
*
|
||||
* @param layout the layout containing items to be cached
|
||||
* @param firstItem the number of first item in layout
|
||||
* @param range the range of current wheel items
|
||||
* @return the new value of first item number
|
||||
*/
|
||||
public int recycleItems(LinearLayout layout, int firstItem, ItemsRange range) {
|
||||
int index = firstItem;
|
||||
for (int i = 0; i < layout.getChildCount();) {
|
||||
if (!range.contains(index)) {
|
||||
recycleView(layout.getChildAt(i), index);
|
||||
layout.removeViewAt(i);
|
||||
if (i == 0) { // first item
|
||||
firstItem++;
|
||||
}
|
||||
} else {
|
||||
i++; // go to next item
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return firstItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets item view
|
||||
* @return the cached view
|
||||
*/
|
||||
public View getItem() {
|
||||
return getCachedView(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets empty item view
|
||||
* @return the cached empty view
|
||||
*/
|
||||
public View getEmptyItem() {
|
||||
return getCachedView(emptyItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all views
|
||||
*/
|
||||
public void clearAll() {
|
||||
if (items != null) {
|
||||
items.clear();
|
||||
}
|
||||
if (emptyItems != null) {
|
||||
emptyItems.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds view to specified cache. Creates a cache list if it is null.
|
||||
* @param view the view to be cached
|
||||
* @param cache the cache list
|
||||
* @return the cache list
|
||||
*/
|
||||
private List<View> addView(View view, List<View> cache) {
|
||||
if (cache == null) {
|
||||
cache = new LinkedList<View>();
|
||||
}
|
||||
|
||||
cache.add(view);
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds view to cache. Determines view type (item view or empty one) by index.
|
||||
* @param view the view to be cached
|
||||
* @param index the index of view
|
||||
*/
|
||||
private void recycleView(View view, int index) {
|
||||
int count = wheel.getViewAdapter().getItemsCount();
|
||||
|
||||
if ((index < 0 || index >= count) && !wheel.isCyclic()) {
|
||||
// empty view
|
||||
emptyItems = addView(view, emptyItems);
|
||||
} else {
|
||||
while (index < 0) {
|
||||
index = count + index;
|
||||
}
|
||||
index %= count;
|
||||
items = addView(view, items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets view from specified cache.
|
||||
* @param cache the cache
|
||||
* @return the first view from cache.
|
||||
*/
|
||||
private View getCachedView(List<View> cache) {
|
||||
if (cache != null && cache.size() > 0) {
|
||||
View view = cache.get(0);
|
||||
cache.remove(0);
|
||||
return view;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Android Wheel Control.
|
||||
* https://code.google.com/p/android-wheel/
|
||||
*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.Scroller;
|
||||
|
||||
/**
|
||||
* Scroller class handles scrolling events and updates the
|
||||
*/
|
||||
public class WheelScroller {
|
||||
/**
|
||||
* Scrolling listener interface
|
||||
*/
|
||||
public interface ScrollingListener {
|
||||
/**
|
||||
* Scrolling callback called when scrolling is performed.
|
||||
* @param distance the distance to scroll
|
||||
*/
|
||||
void onScroll(int distance);
|
||||
|
||||
/**
|
||||
* Starting callback called when scrolling is started
|
||||
*/
|
||||
void onStarted();
|
||||
|
||||
/**
|
||||
* Finishing callback called after justifying
|
||||
*/
|
||||
void onFinished();
|
||||
|
||||
/**
|
||||
* Justifying callback called to justify a view when scrolling is ended
|
||||
*/
|
||||
void onJustify();
|
||||
}
|
||||
|
||||
/** Scrolling duration */
|
||||
private static final int SCROLLING_DURATION = 400;
|
||||
|
||||
/** Minimum delta for scrolling */
|
||||
public static final int MIN_DELTA_FOR_SCROLLING = 1;
|
||||
|
||||
// Listener
|
||||
private ScrollingListener listener;
|
||||
|
||||
// Context
|
||||
private Context context;
|
||||
|
||||
// Scrolling
|
||||
private GestureDetector gestureDetector;
|
||||
private Scroller scroller;
|
||||
private int lastScrollY;
|
||||
private float lastTouchedY;
|
||||
private boolean isScrollingPerformed;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
* @param listener the scrolling listener
|
||||
*/
|
||||
public WheelScroller(Context context, ScrollingListener listener) {
|
||||
gestureDetector = new GestureDetector(context, gestureListener);
|
||||
gestureDetector.setIsLongpressEnabled(false);
|
||||
|
||||
scroller = new Scroller(context);
|
||||
|
||||
this.listener = listener;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the specified scrolling interpolator
|
||||
* @param interpolator the interpolator
|
||||
*/
|
||||
public void setInterpolator(Interpolator interpolator) {
|
||||
scroller.forceFinished(true);
|
||||
scroller = new Scroller(context, interpolator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll the wheel
|
||||
* @param distance the scrolling distance
|
||||
* @param time the scrolling duration
|
||||
*/
|
||||
public void scroll(int distance, int time) {
|
||||
scroller.forceFinished(true);
|
||||
|
||||
lastScrollY = 0;
|
||||
|
||||
scroller.startScroll(0, 0, 0, distance, time != 0 ? time : SCROLLING_DURATION);
|
||||
setNextMessage(MESSAGE_SCROLL);
|
||||
|
||||
startScrolling();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops scrolling
|
||||
*/
|
||||
public void stopScrolling() {
|
||||
scroller.forceFinished(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Touch event
|
||||
* @param event the motion event
|
||||
* @return
|
||||
*/
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
lastTouchedY = event.getY();
|
||||
scroller.forceFinished(true);
|
||||
clearMessages();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
// perform scrolling
|
||||
int distanceY = (int)(event.getY() - lastTouchedY);
|
||||
if (distanceY != 0) {
|
||||
startScrolling();
|
||||
listener.onScroll(distanceY);
|
||||
lastTouchedY = event.getY();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gestureDetector.onTouchEvent(event) && event.getAction() == MotionEvent.ACTION_UP) {
|
||||
justify();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// gesture listener
|
||||
private SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() {
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
// Do scrolling in onTouchEvent() since onScroll() are not call immediately
|
||||
// when user touch and move the wheel
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
lastScrollY = 0;
|
||||
final int maxY = 0x7FFFFFFF;
|
||||
final int minY = -maxY;
|
||||
scroller.fling(0, lastScrollY, 0, (int) -velocityY, 0, 0, minY, maxY);
|
||||
setNextMessage(MESSAGE_SCROLL);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Messages
|
||||
private final int MESSAGE_SCROLL = 0;
|
||||
private final int MESSAGE_JUSTIFY = 1;
|
||||
|
||||
/**
|
||||
* Set next message to queue. Clears queue before.
|
||||
*
|
||||
* @param message the message to set
|
||||
*/
|
||||
private void setNextMessage(int message) {
|
||||
clearMessages();
|
||||
animationHandler.sendEmptyMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears messages from queue
|
||||
*/
|
||||
private void clearMessages() {
|
||||
animationHandler.removeMessages(MESSAGE_SCROLL);
|
||||
animationHandler.removeMessages(MESSAGE_JUSTIFY);
|
||||
}
|
||||
|
||||
// animation handler
|
||||
private Handler animationHandler = new Handler() {
|
||||
public void handleMessage(Message msg) {
|
||||
scroller.computeScrollOffset();
|
||||
int currY = scroller.getCurrY();
|
||||
int delta = lastScrollY - currY;
|
||||
lastScrollY = currY;
|
||||
if (delta != 0) {
|
||||
listener.onScroll(delta);
|
||||
}
|
||||
|
||||
// scrolling is not finished when it comes to final Y
|
||||
// so, finish it manually
|
||||
if (Math.abs(currY - scroller.getFinalY()) < MIN_DELTA_FOR_SCROLLING) {
|
||||
currY = scroller.getFinalY();
|
||||
scroller.forceFinished(true);
|
||||
}
|
||||
if (!scroller.isFinished()) {
|
||||
animationHandler.sendEmptyMessage(msg.what);
|
||||
} else if (msg.what == MESSAGE_SCROLL) {
|
||||
justify();
|
||||
} else {
|
||||
finishScrolling();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Justifies wheel
|
||||
*/
|
||||
private void justify() {
|
||||
listener.onJustify();
|
||||
setNextMessage(MESSAGE_JUSTIFY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts scrolling
|
||||
*/
|
||||
private void startScrolling() {
|
||||
if (!isScrollingPerformed) {
|
||||
isScrollingPerformed = true;
|
||||
listener.onStarted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes scrolling
|
||||
*/
|
||||
void finishScrolling() {
|
||||
if (isScrollingPerformed) {
|
||||
listener.onFinished();
|
||||
isScrollingPerformed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,1058 @@
|
||||
/*
|
||||
* Android Wheel Control.
|
||||
* https://code.google.com/p/android-wheel/
|
||||
*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.GradientDrawable.Orientation;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.adapters.WheelViewAdapter;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Numeric wheel view.
|
||||
*
|
||||
* @author Yuri Kanivets
|
||||
*/
|
||||
public class WheelView extends View {
|
||||
|
||||
/**
|
||||
* 滚轮从上到下背景逐渐变淡,到中间,逆反改变
|
||||
*/
|
||||
private int[] SHADOWS_COLORS = new int[] { 0xefF9F9F9, 0xcfF9F9F9, 0x3fF9F9F9 };
|
||||
|
||||
/**
|
||||
* Top and bottom items offset (to hide that)
|
||||
*/
|
||||
private static final int ITEM_OFFSET_PERCENT = 0;
|
||||
|
||||
/**
|
||||
* 滚轮左右间隔距离
|
||||
*/
|
||||
private static final int PADDING = 5;
|
||||
|
||||
/**
|
||||
* 滚轮显示的item个数
|
||||
*/
|
||||
private static final int DEF_VISIBLE_ITEMS = 5;
|
||||
|
||||
// Wheel Values
|
||||
private int currentItem = 0;
|
||||
|
||||
// Count of visible items
|
||||
private int visibleItems = DEF_VISIBLE_ITEMS;
|
||||
|
||||
// Item height
|
||||
private int itemHeight = 0;
|
||||
|
||||
// Center Line
|
||||
private Drawable centerDrawable;
|
||||
|
||||
// Wheel drawables
|
||||
private int wheelBackground = R.drawable.wheel_bg;
|
||||
|
||||
private int wheelForeground = R.drawable.wheel_val;
|
||||
|
||||
// Shadows drawables
|
||||
private GradientDrawable topShadow;
|
||||
|
||||
private GradientDrawable bottomShadow;
|
||||
|
||||
// Draw Shadows
|
||||
private boolean drawShadows = true;
|
||||
|
||||
// Scrolling
|
||||
private WheelScroller scroller;
|
||||
|
||||
private boolean isScrollingPerformed;
|
||||
|
||||
private int scrollingOffset;
|
||||
|
||||
/**
|
||||
* 滚轮是否循环滚动
|
||||
*/
|
||||
boolean isCyclic = false;
|
||||
|
||||
// Items layout
|
||||
private LinearLayout itemsLayout;
|
||||
|
||||
// The number of first item in layout
|
||||
private int firstItem;
|
||||
|
||||
// View adapter
|
||||
private WheelViewAdapter viewAdapter;
|
||||
|
||||
// Recycle
|
||||
private WheelRecycle recycle = new WheelRecycle(this);
|
||||
|
||||
// Listeners
|
||||
private List<OnWheelChangedListener> changingListeners = new LinkedList<OnWheelChangedListener>();
|
||||
|
||||
private List<OnWheelScrollListener> scrollingListeners = new LinkedList<OnWheelScrollListener>();
|
||||
|
||||
private List<OnWheelClickedListener> clickingListeners = new LinkedList<OnWheelClickedListener>();
|
||||
|
||||
/**
|
||||
* 中间线的颜色
|
||||
*/
|
||||
private String lineColorStr = "#C7C7C7";
|
||||
|
||||
/**
|
||||
* 中间线的宽度
|
||||
*/
|
||||
private int lineWidth = 3;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public WheelView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initData(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public WheelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initData(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public WheelView(Context context) {
|
||||
super(context);
|
||||
initData(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes class data
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
private void initData(Context context) {
|
||||
scroller = new WheelScroller(getContext(), scrollingListener);
|
||||
}
|
||||
|
||||
// Scrolling listener
|
||||
WheelScroller.ScrollingListener scrollingListener = new WheelScroller.ScrollingListener() {
|
||||
@Override
|
||||
public void onStarted() {
|
||||
isScrollingPerformed = true;
|
||||
notifyScrollingListenersAboutStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(int distance) {
|
||||
doScroll(distance);
|
||||
|
||||
int height = getHeight();
|
||||
if (scrollingOffset > height) {
|
||||
scrollingOffset = height;
|
||||
scroller.stopScrolling();
|
||||
}
|
||||
else if (scrollingOffset < -height) {
|
||||
scrollingOffset = -height;
|
||||
scroller.stopScrolling();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinished() {
|
||||
if (isScrollingPerformed) {
|
||||
notifyScrollingListenersAboutEnd();
|
||||
isScrollingPerformed = false;
|
||||
}
|
||||
|
||||
scrollingOffset = 0;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJustify() {
|
||||
if (Math.abs(scrollingOffset) > WheelScroller.MIN_DELTA_FOR_SCROLLING) {
|
||||
scroller.scroll(scrollingOffset, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public String getLineColorStr() {
|
||||
return lineColorStr == null ? "" : lineColorStr;
|
||||
}
|
||||
|
||||
public void setLineColorStr(String lineColorStr) {
|
||||
this.lineColorStr = lineColorStr;
|
||||
}
|
||||
|
||||
public int getLineWidth() {
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
public void setLineWidth(int lineWidth) {
|
||||
this.lineWidth = lineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the specified scrolling interpolator
|
||||
*
|
||||
* @param interpolator the interpolator
|
||||
*/
|
||||
public void setInterpolator(Interpolator interpolator) {
|
||||
scroller.setInterpolator(interpolator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets count of visible items
|
||||
*
|
||||
* @return the count of visible items
|
||||
*/
|
||||
public int getVisibleItems() {
|
||||
return visibleItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the desired count of visible items.
|
||||
* Actual amount of visible items depends on wheel layout parameters.
|
||||
* To apply changes and rebuild view call measure().
|
||||
*
|
||||
* @param count the desired count for visible items
|
||||
*/
|
||||
public void setVisibleItems(int count) {
|
||||
visibleItems = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets view adapter
|
||||
*
|
||||
* @return the view adapter
|
||||
*/
|
||||
public WheelViewAdapter getViewAdapter() {
|
||||
return viewAdapter;
|
||||
}
|
||||
|
||||
// Adapter listener
|
||||
private DataSetObserver dataObserver = new DataSetObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
invalidateWheel(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInvalidated() {
|
||||
invalidateWheel(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets view adapter. Usually new adapters contain different views, so
|
||||
* it needs to rebuild view by calling measure().
|
||||
*
|
||||
* @param viewAdapter the view adapter
|
||||
*/
|
||||
public void setViewAdapter(WheelViewAdapter viewAdapter) {
|
||||
if (this.viewAdapter != null) {
|
||||
this.viewAdapter.unregisterDataSetObserver(dataObserver);
|
||||
}
|
||||
this.viewAdapter = viewAdapter;
|
||||
if (this.viewAdapter != null) {
|
||||
this.viewAdapter.registerDataSetObserver(dataObserver);
|
||||
}
|
||||
|
||||
invalidateWheel(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds wheel changing listener
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void addChangingListener(OnWheelChangedListener listener) {
|
||||
changingListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes wheel changing listener
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void removeChangingListener(OnWheelChangedListener listener) {
|
||||
changingListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies changing listeners
|
||||
*
|
||||
* @param oldValue the old wheel value
|
||||
* @param newValue the new wheel value
|
||||
*/
|
||||
protected void notifyChangingListeners(int oldValue, int newValue) {
|
||||
for (OnWheelChangedListener listener : changingListeners) {
|
||||
listener.onChanged(this, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds wheel scrolling listener
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void addScrollingListener(OnWheelScrollListener listener) {
|
||||
scrollingListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes wheel scrolling listener
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void removeScrollingListener(OnWheelScrollListener listener) {
|
||||
scrollingListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies listeners about starting scrolling
|
||||
*/
|
||||
protected void notifyScrollingListenersAboutStart() {
|
||||
for (OnWheelScrollListener listener : scrollingListeners) {
|
||||
listener.onScrollingStarted(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies listeners about ending scrolling
|
||||
*/
|
||||
protected void notifyScrollingListenersAboutEnd() {
|
||||
for (OnWheelScrollListener listener : scrollingListeners) {
|
||||
listener.onScrollingFinished(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds wheel clicking listener
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void addClickingListener(OnWheelClickedListener listener) {
|
||||
clickingListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes wheel clicking listener
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void removeClickingListener(OnWheelClickedListener listener) {
|
||||
clickingListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies listeners about clicking
|
||||
*/
|
||||
protected void notifyClickListenersAboutClick(int item) {
|
||||
for (OnWheelClickedListener listener : clickingListeners) {
|
||||
listener.onItemClicked(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current value
|
||||
*
|
||||
* @return the current value
|
||||
*/
|
||||
public int getCurrentItem() {
|
||||
return currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current item. Does nothing when index is wrong.
|
||||
*
|
||||
* @param index the item index
|
||||
* @param animated the animation flag
|
||||
*/
|
||||
public void setCurrentItem(int index, boolean animated) {
|
||||
if (viewAdapter == null || viewAdapter.getItemsCount() == 0) {
|
||||
return; // throw?
|
||||
}
|
||||
|
||||
int itemCount = viewAdapter.getItemsCount();
|
||||
if (index < 0 || index >= itemCount) {
|
||||
if (isCyclic) {
|
||||
while (index < 0) {
|
||||
index += itemCount;
|
||||
}
|
||||
index %= itemCount;
|
||||
}
|
||||
else {
|
||||
return; // throw?
|
||||
}
|
||||
}
|
||||
if (index != currentItem) {
|
||||
if (animated) {
|
||||
int itemsToScroll = index - currentItem;
|
||||
if (isCyclic) {
|
||||
int scroll = itemCount + Math.min(index, currentItem) - Math.max(index, currentItem);
|
||||
if (scroll < Math.abs(itemsToScroll)) {
|
||||
itemsToScroll = itemsToScroll < 0 ? scroll : -scroll;
|
||||
}
|
||||
}
|
||||
scroll(itemsToScroll, 0);
|
||||
}
|
||||
else {
|
||||
scrollingOffset = 0;
|
||||
|
||||
int old = currentItem;
|
||||
currentItem = index;
|
||||
|
||||
notifyChangingListeners(old, currentItem);
|
||||
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current item w/o animation. Does nothing when index is wrong.
|
||||
*
|
||||
* @param index the item index
|
||||
*/
|
||||
public void setCurrentItem(int index) {
|
||||
setCurrentItem(index, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if wheel is cyclic. That means before the 1st item there is shown the last one
|
||||
*
|
||||
* @return true if wheel is cyclic
|
||||
*/
|
||||
public boolean isCyclic() {
|
||||
return isCyclic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set wheel cyclic flag
|
||||
*
|
||||
* @param isCyclic the flag to set
|
||||
*/
|
||||
public void setCyclic(boolean isCyclic) {
|
||||
this.isCyclic = isCyclic;
|
||||
invalidateWheel(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether shadows are drawn
|
||||
*
|
||||
* @return true is shadows are drawn
|
||||
*/
|
||||
public boolean drawShadows() {
|
||||
return drawShadows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether shadows should be drawn
|
||||
*
|
||||
* @param drawShadows flag as true or false
|
||||
*/
|
||||
public void setDrawShadows(boolean drawShadows) {
|
||||
this.drawShadows = drawShadows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow gradient color
|
||||
*
|
||||
* @param start
|
||||
* @param middle
|
||||
* @param end
|
||||
*/
|
||||
public void setShadowColor(int start, int middle, int end) {
|
||||
SHADOWS_COLORS = new int[] { start, middle, end };
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawable for the wheel background
|
||||
*
|
||||
* @param resource
|
||||
*/
|
||||
public void setWheelBackground(int resource) {
|
||||
wheelBackground = resource;
|
||||
setBackgroundResource(wheelBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawable for the wheel foreground
|
||||
*
|
||||
* @param resource
|
||||
*/
|
||||
public void setWheelForeground(int resource) {
|
||||
wheelForeground = resource;
|
||||
centerDrawable = getContext().getResources().getDrawable(wheelForeground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates wheel
|
||||
*
|
||||
* @param clearCaches if true then cached views will be clear
|
||||
*/
|
||||
public void invalidateWheel(boolean clearCaches) {
|
||||
if (clearCaches) {
|
||||
recycle.clearAll();
|
||||
if (itemsLayout != null) {
|
||||
itemsLayout.removeAllViews();
|
||||
}
|
||||
scrollingOffset = 0;
|
||||
}
|
||||
else if (itemsLayout != null) {
|
||||
// cache all items
|
||||
recycle.recycleItems(itemsLayout, firstItem, new ItemsRange());
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes resources
|
||||
*/
|
||||
private void initResourcesIfNecessary() {
|
||||
if (centerDrawable == null) {
|
||||
centerDrawable = getContext().getResources().getDrawable(wheelForeground);
|
||||
}
|
||||
|
||||
if (topShadow == null) {
|
||||
topShadow = new GradientDrawable(Orientation.TOP_BOTTOM, SHADOWS_COLORS);
|
||||
}
|
||||
|
||||
if (bottomShadow == null) {
|
||||
bottomShadow = new GradientDrawable(Orientation.BOTTOM_TOP, SHADOWS_COLORS);
|
||||
}
|
||||
|
||||
setBackgroundResource(wheelBackground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates desired height for layout
|
||||
*
|
||||
* @param layout the source layout
|
||||
* @return the desired layout height
|
||||
*/
|
||||
private int getDesiredHeight(LinearLayout layout) {
|
||||
if (layout != null && layout.getChildAt(0) != null) {
|
||||
itemHeight = layout.getChildAt(0).getMeasuredHeight();
|
||||
}
|
||||
|
||||
int desired = itemHeight * visibleItems - itemHeight * ITEM_OFFSET_PERCENT / 50;
|
||||
|
||||
return Math.max(desired, getSuggestedMinimumHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns height of wheel item
|
||||
*
|
||||
* @return the item height
|
||||
*/
|
||||
private int getItemHeight() {
|
||||
if (itemHeight != 0) {
|
||||
return itemHeight;
|
||||
}
|
||||
|
||||
if (itemsLayout != null && itemsLayout.getChildAt(0) != null) {
|
||||
itemHeight = itemsLayout.getChildAt(0).getHeight();
|
||||
return itemHeight;
|
||||
}
|
||||
|
||||
return getHeight() / visibleItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates control width and creates text layouts
|
||||
*
|
||||
* @param widthSize the input layout width
|
||||
* @param mode the layout mode
|
||||
* @return the calculated control width
|
||||
*/
|
||||
private int calculateLayoutWidth(int widthSize, int mode) {
|
||||
initResourcesIfNecessary();
|
||||
|
||||
// TODO: make it static
|
||||
itemsLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||
itemsLayout.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.UNSPECIFIED),
|
||||
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
|
||||
int width = itemsLayout.getMeasuredWidth();
|
||||
|
||||
if (mode == MeasureSpec.EXACTLY) {
|
||||
width = widthSize;
|
||||
}
|
||||
else {
|
||||
width += 2 * PADDING;
|
||||
|
||||
// Check against our minimum width
|
||||
width = Math.max(width, getSuggestedMinimumWidth());
|
||||
|
||||
if (mode == MeasureSpec.AT_MOST && widthSize < width) {
|
||||
width = widthSize;
|
||||
}
|
||||
}
|
||||
|
||||
itemsLayout.measure(MeasureSpec.makeMeasureSpec(width - 2 * PADDING, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
buildViewForMeasuring();
|
||||
|
||||
int width = calculateLayoutWidth(widthSize, widthMode);
|
||||
|
||||
int height;
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
height = heightSize;
|
||||
}
|
||||
else {
|
||||
height = getDesiredHeight(itemsLayout);
|
||||
|
||||
if (heightMode == MeasureSpec.AT_MOST) {
|
||||
height = Math.min(height, heightSize);
|
||||
}
|
||||
}
|
||||
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
layout(r - l, b - t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets layouts width and height
|
||||
*
|
||||
* @param width the layout width
|
||||
* @param height the layout height
|
||||
*/
|
||||
private void layout(int width, int height) {
|
||||
int itemsWidth = width - 2 * PADDING;
|
||||
|
||||
itemsLayout.layout(0, 0, itemsWidth, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
if (viewAdapter != null && viewAdapter.getItemsCount() > 0) {
|
||||
updateView();
|
||||
|
||||
drawItems(canvas);
|
||||
drawCenterRect(canvas);
|
||||
}
|
||||
|
||||
if (drawShadows)
|
||||
drawShadows(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws shadows on top and bottom of control
|
||||
*
|
||||
* @param canvas the canvas for drawing
|
||||
*/
|
||||
private void drawShadows(Canvas canvas) {
|
||||
/*/ Modified by wulianghuan 2014-11-25
|
||||
int height = (int)(1.5 * getItemHeight());
|
||||
//*/
|
||||
|
||||
//从中间到顶部渐变处理
|
||||
int count = getVisibleItems() == 2 ? 1 : getVisibleItems() / 2;
|
||||
int height = (int) (count * getItemHeight());
|
||||
|
||||
topShadow.setBounds(0, 0, getWidth(), height);
|
||||
topShadow.draw(canvas);
|
||||
|
||||
bottomShadow.setBounds(0, getHeight() - height, getWidth(), getHeight());
|
||||
bottomShadow.draw(canvas);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws items
|
||||
*
|
||||
* @param canvas the canvas for drawing
|
||||
*/
|
||||
private void drawItems(Canvas canvas) {
|
||||
canvas.save();
|
||||
|
||||
int top = (currentItem - firstItem) * getItemHeight() + (getItemHeight() - getHeight()) / 2;
|
||||
canvas.translate(PADDING, -top + scrollingOffset);
|
||||
|
||||
itemsLayout.draw(canvas);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws rect for current value
|
||||
*
|
||||
* @param canvas the canvas for drawing
|
||||
*/
|
||||
private void drawCenterRect(Canvas canvas) {
|
||||
int center = getHeight() / 2;
|
||||
int offset = (int) (getItemHeight() / 2 * 1.2);
|
||||
/*/ Remarked by wulianghuan 2014-11-27 使用自己的画线,而不是描边
|
||||
Rect rect = new Rect(left, top, right, bottom)
|
||||
centerDrawable.setBounds(bounds)
|
||||
centerDrawable.setBounds(0, center - offset, getWidth(), center + offset);
|
||||
centerDrawable.draw(canvas);
|
||||
//*/
|
||||
Paint paint = new Paint();
|
||||
if (getLineColorStr().startsWith("#")) {
|
||||
paint.setColor(Color.parseColor(getLineColorStr()));
|
||||
}
|
||||
else {
|
||||
paint.setColor(Color.parseColor("#" + getLineColorStr()));
|
||||
}
|
||||
// 设置线宽
|
||||
if (getLineWidth() > 3) {
|
||||
paint.setStrokeWidth((float) getLineWidth());
|
||||
}
|
||||
else {
|
||||
paint.setStrokeWidth((float) 3);
|
||||
|
||||
}
|
||||
|
||||
// 绘制上边直线
|
||||
canvas.drawLine(0, center - offset, getWidth(), center - offset, paint);
|
||||
// 绘制下边直线
|
||||
canvas.drawLine(0, center + offset, getWidth(), center + offset, paint);
|
||||
//*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!isEnabled() || getViewAdapter() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (getParent() != null) {
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!isScrollingPerformed) {
|
||||
int distance = (int) event.getY() - getHeight() / 2;
|
||||
if (distance > 0) {
|
||||
distance += getItemHeight() / 2;
|
||||
}
|
||||
else {
|
||||
distance -= getItemHeight() / 2;
|
||||
}
|
||||
int items = distance / getItemHeight();
|
||||
if (items != 0 && isValidItemIndex(currentItem + items)) {
|
||||
notifyClickListenersAboutClick(currentItem + items);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return scroller.onTouchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the wheel
|
||||
*
|
||||
* @param delta the scrolling value
|
||||
*/
|
||||
private void doScroll(int delta) {
|
||||
scrollingOffset += delta;
|
||||
|
||||
int itemHeight = getItemHeight();
|
||||
int count = scrollingOffset / itemHeight;
|
||||
|
||||
int pos = currentItem - count;
|
||||
int itemCount = viewAdapter.getItemsCount();
|
||||
|
||||
int fixPos = scrollingOffset % itemHeight;
|
||||
if (Math.abs(fixPos) <= itemHeight / 2) {
|
||||
fixPos = 0;
|
||||
}
|
||||
if (isCyclic && itemCount > 0) {
|
||||
if (fixPos > 0) {
|
||||
pos--;
|
||||
count++;
|
||||
}
|
||||
else if (fixPos < 0) {
|
||||
pos++;
|
||||
count--;
|
||||
}
|
||||
// fix position by rotating
|
||||
while (pos < 0) {
|
||||
pos += itemCount;
|
||||
}
|
||||
pos %= itemCount;
|
||||
}
|
||||
else {
|
||||
//
|
||||
if (pos < 0) {
|
||||
count = currentItem;
|
||||
pos = 0;
|
||||
}
|
||||
else if (pos >= itemCount) {
|
||||
count = currentItem - itemCount + 1;
|
||||
pos = itemCount - 1;
|
||||
}
|
||||
else if (pos > 0 && fixPos > 0) {
|
||||
pos--;
|
||||
count++;
|
||||
}
|
||||
else if (pos < itemCount - 1 && fixPos < 0) {
|
||||
pos++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
int offset = scrollingOffset;
|
||||
if (pos != currentItem) {
|
||||
setCurrentItem(pos, false);
|
||||
}
|
||||
else {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// update offset
|
||||
scrollingOffset = offset - count * itemHeight;
|
||||
if (scrollingOffset > getHeight()) {
|
||||
scrollingOffset = scrollingOffset % getHeight() + getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll the wheel
|
||||
*
|
||||
* @param time scrolling duration
|
||||
*/
|
||||
public void scroll(int itemsToScroll, int time) {
|
||||
int distance = itemsToScroll * getItemHeight() - scrollingOffset;
|
||||
scroller.scroll(distance, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates range for wheel items
|
||||
*
|
||||
* @return the items range
|
||||
*/
|
||||
private ItemsRange getItemsRange() {
|
||||
if (getItemHeight() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int first = currentItem;
|
||||
int count = 1;
|
||||
|
||||
while (count * getItemHeight() < getHeight()) {
|
||||
first--;
|
||||
count += 2; // top + bottom items
|
||||
}
|
||||
|
||||
if (scrollingOffset != 0) {
|
||||
if (scrollingOffset > 0) {
|
||||
first--;
|
||||
}
|
||||
count++;
|
||||
|
||||
// process empty items above the first or below the second
|
||||
int emptyItems = scrollingOffset / getItemHeight();
|
||||
first -= emptyItems;
|
||||
count += Math.asin(emptyItems);
|
||||
}
|
||||
return new ItemsRange(first, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds wheel items if necessary. Caches all unused items.
|
||||
*
|
||||
* @return true if items are rebuilt
|
||||
*/
|
||||
private boolean rebuildItems() {
|
||||
boolean updated = false;
|
||||
ItemsRange range = getItemsRange();
|
||||
if (itemsLayout != null) {
|
||||
int first = recycle.recycleItems(itemsLayout, firstItem, range);
|
||||
updated = firstItem != first;
|
||||
firstItem = first;
|
||||
}
|
||||
else {
|
||||
createItemsLayout();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
updated = firstItem != range.getFirst() || itemsLayout.getChildCount() != range.getCount();
|
||||
}
|
||||
|
||||
if (firstItem > range.getFirst() && firstItem <= range.getLast()) {
|
||||
for (int i = firstItem - 1; i >= range.getFirst(); i--) {
|
||||
if (!addViewItem(i, true)) {
|
||||
break;
|
||||
}
|
||||
firstItem = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
firstItem = range.getFirst();
|
||||
}
|
||||
|
||||
int first = firstItem;
|
||||
for (int i = itemsLayout.getChildCount(); i < range.getCount(); i++) {
|
||||
if (!addViewItem(firstItem + i, false) && itemsLayout.getChildCount() == 0) {
|
||||
first++;
|
||||
}
|
||||
}
|
||||
firstItem = first;
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates view. Rebuilds items and label if necessary, recalculate items sizes.
|
||||
*/
|
||||
private void updateView() {
|
||||
if (rebuildItems()) {
|
||||
calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY);
|
||||
layout(getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates item layouts if necessary
|
||||
*/
|
||||
private void createItemsLayout() {
|
||||
if (itemsLayout == null) {
|
||||
itemsLayout = new LinearLayout(getContext());
|
||||
itemsLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds view for measuring
|
||||
*/
|
||||
private void buildViewForMeasuring() {
|
||||
// clear all items
|
||||
if (itemsLayout != null) {
|
||||
recycle.recycleItems(itemsLayout, firstItem, new ItemsRange());
|
||||
}
|
||||
else {
|
||||
createItemsLayout();
|
||||
}
|
||||
|
||||
// add views
|
||||
int addItems = visibleItems / 2;
|
||||
for (int i = currentItem + addItems; i >= currentItem - addItems; i--) {
|
||||
if (addViewItem(i, true)) {
|
||||
firstItem = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds view for item to items layout
|
||||
*
|
||||
* @param index the item index
|
||||
* @param first the flag indicates if view should be first
|
||||
* @return true if corresponding item exists and is added
|
||||
*/
|
||||
private boolean addViewItem(int index, boolean first) {
|
||||
View view = getItemView(index);
|
||||
if (view != null) {
|
||||
if (first) {
|
||||
itemsLayout.addView(view, 0);
|
||||
}
|
||||
else {
|
||||
itemsLayout.addView(view);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether intem index is valid
|
||||
*
|
||||
* @param index the item index
|
||||
* @return true if item index is not out of bounds or the wheel is cyclic
|
||||
*/
|
||||
private boolean isValidItemIndex(int index) {
|
||||
return viewAdapter != null && viewAdapter.getItemsCount() > 0
|
||||
&& (isCyclic || index >= 0 && index < viewAdapter.getItemsCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view for specified item
|
||||
*
|
||||
* @param index the item index
|
||||
* @return item view or empty view if index is out of bounds
|
||||
*/
|
||||
private View getItemView(int index) {
|
||||
if (viewAdapter == null || viewAdapter.getItemsCount() == 0) {
|
||||
return null;
|
||||
}
|
||||
int count = viewAdapter.getItemsCount();
|
||||
if (!isValidItemIndex(index)) {
|
||||
return viewAdapter.getEmptyItem(recycle.getEmptyItem(), itemsLayout);
|
||||
}
|
||||
else {
|
||||
while (index < 0) {
|
||||
index = count + index;
|
||||
}
|
||||
}
|
||||
|
||||
index %= count;
|
||||
return viewAdapter.getItem(index, recycle.getItem(), itemsLayout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops scrolling
|
||||
*/
|
||||
public void stopScrolling() {
|
||||
scroller.stopScrolling();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel.adapters;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.database.DataSetObserver;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Abstract Wheel adapter.
|
||||
*/
|
||||
public abstract class AbstractWheelAdapter implements WheelViewAdapter {
|
||||
// Observers
|
||||
private List<DataSetObserver> datasetObservers;
|
||||
|
||||
@Override
|
||||
public View getEmptyItem(View convertView, ViewGroup parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDataSetObserver(DataSetObserver observer) {
|
||||
if (datasetObservers == null) {
|
||||
datasetObservers = new LinkedList<DataSetObserver>();
|
||||
}
|
||||
datasetObservers.add(observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterDataSetObserver(DataSetObserver observer) {
|
||||
if (datasetObservers != null) {
|
||||
datasetObservers.remove(observer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies observers about data changing
|
||||
*/
|
||||
protected void notifyDataChangedEvent() {
|
||||
if (datasetObservers != null) {
|
||||
for (DataSetObserver observer : datasetObservers) {
|
||||
observer.onChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies observers about invalidating data
|
||||
*/
|
||||
protected void notifyDataInvalidatedEvent() {
|
||||
if (datasetObservers != null) {
|
||||
for (DataSetObserver observer : datasetObservers) {
|
||||
observer.onInvalidated();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Abstract wheel adapter provides common functionality for adapters.
|
||||
*/
|
||||
public abstract class AbstractWheelTextAdapter extends AbstractWheelAdapter {
|
||||
|
||||
/** Text view resource. Used as a default view for adapter. */
|
||||
public static final int TEXT_VIEW_ITEM_RESOURCE = -1;
|
||||
|
||||
/** No resource constant. */
|
||||
protected static final int NO_RESOURCE = 0;
|
||||
|
||||
/** Default text color */
|
||||
public static final int DEFAULT_TEXT_COLOR = 0xFF585858;
|
||||
|
||||
/** Default text color */
|
||||
public static final int LABEL_COLOR = 0xFF700070;
|
||||
|
||||
/** Default text size */
|
||||
public static final int DEFAULT_TEXT_SIZE = 18;
|
||||
|
||||
// Text settings
|
||||
private int textColor = DEFAULT_TEXT_COLOR;
|
||||
|
||||
private int textSize = DEFAULT_TEXT_SIZE;
|
||||
|
||||
private int padding = 5;
|
||||
|
||||
// Current context
|
||||
protected Context context;
|
||||
|
||||
// Layout inflater
|
||||
protected LayoutInflater inflater;
|
||||
|
||||
// Items resources
|
||||
protected int itemResourceId;
|
||||
|
||||
protected int itemTextResourceId;
|
||||
|
||||
// Empty items resources
|
||||
protected int emptyItemResourceId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
*/
|
||||
protected AbstractWheelTextAdapter(Context context) {
|
||||
this(context, TEXT_VIEW_ITEM_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
* @param itemResource the resource ID for a layout file containing a TextView to use when instantiating items views
|
||||
*/
|
||||
protected AbstractWheelTextAdapter(Context context, int itemResource) {
|
||||
this(context, itemResource, NO_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
* @param itemResource the resource ID for a layout file containing a TextView to use when instantiating items views
|
||||
* @param itemTextResource the resource ID for a text view in the item layout
|
||||
*/
|
||||
protected AbstractWheelTextAdapter(Context context, int itemResource, int itemTextResource) {
|
||||
this.context = context;
|
||||
itemResourceId = itemResource;
|
||||
itemTextResourceId = itemTextResource;
|
||||
|
||||
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text color
|
||||
* @return the text color
|
||||
*/
|
||||
public int getTextColor() {
|
||||
return textColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text color
|
||||
* @param textColor the text color to set
|
||||
*/
|
||||
public void setTextColor(int textColor) {
|
||||
this.textColor = textColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* item间距
|
||||
* @return
|
||||
*/
|
||||
public int getPadding() {
|
||||
return padding;
|
||||
}
|
||||
|
||||
public void setPadding(int padding) {
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text size
|
||||
* @return the text size
|
||||
*/
|
||||
public int getTextSize() {
|
||||
return textSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text size
|
||||
* @param textSize the text size to set
|
||||
*/
|
||||
public void setTextSize(int textSize) {
|
||||
this.textSize = textSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource Id for items views
|
||||
* @return the item resource Id
|
||||
*/
|
||||
public int getItemResource() {
|
||||
return itemResourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource Id for items views
|
||||
* @param itemResourceId the resource Id to set
|
||||
*/
|
||||
public void setItemResource(int itemResourceId) {
|
||||
this.itemResourceId = itemResourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource Id for text view in item layout
|
||||
* @return the item text resource Id
|
||||
*/
|
||||
public int getItemTextResource() {
|
||||
return itemTextResourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource Id for text view in item layout
|
||||
* @param itemTextResourceId the item text resource Id to set
|
||||
*/
|
||||
public void setItemTextResource(int itemTextResourceId) {
|
||||
this.itemTextResourceId = itemTextResourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource Id for empty items views
|
||||
* @return the empty item resource Id
|
||||
*/
|
||||
public int getEmptyItemResource() {
|
||||
return emptyItemResourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource Id for empty items views
|
||||
* @param emptyItemResourceId the empty item resource Id to set
|
||||
*/
|
||||
public void setEmptyItemResource(int emptyItemResourceId) {
|
||||
this.emptyItemResourceId = emptyItemResourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns text for specified item
|
||||
* @param index the item index
|
||||
* @return the text of specified items
|
||||
*/
|
||||
protected abstract CharSequence getItemText(int index);
|
||||
|
||||
@Override
|
||||
public View getItem(int index, View convertView, ViewGroup parent) {
|
||||
if (index >= 0 && index < getItemsCount()) {
|
||||
if (convertView == null) {
|
||||
convertView = getView(itemResourceId, parent);
|
||||
}
|
||||
TextView textView = getTextView(convertView, itemTextResourceId);
|
||||
if (textView != null) {
|
||||
CharSequence text = getItemText(index);
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
textView.setText(text);
|
||||
|
||||
if (itemResourceId == TEXT_VIEW_ITEM_RESOURCE) {
|
||||
configureTextView(textView);
|
||||
}
|
||||
}
|
||||
return convertView;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getEmptyItem(View convertView, ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
convertView = getView(emptyItemResourceId, parent);
|
||||
}
|
||||
if (emptyItemResourceId == TEXT_VIEW_ITEM_RESOURCE && convertView instanceof TextView) {
|
||||
configureTextView((TextView) convertView);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures text view. Is called for the TEXT_VIEW_ITEM_RESOURCE views.
|
||||
* @param view the text view to be configured
|
||||
*/
|
||||
protected void configureTextView(TextView view) {
|
||||
view.setTextColor(textColor);
|
||||
view.setGravity(Gravity.CENTER);
|
||||
view.setPadding(0, padding, 0, padding);
|
||||
view.setTextSize(textSize);
|
||||
// view.setEllipsize(TextUtils.TruncateAt.END);
|
||||
// view.setLines(1);
|
||||
// view.setCompoundDrawablePadding(20);
|
||||
// view.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a text view from view
|
||||
* @param view the text view or layout containing it
|
||||
* @param textResource the text resource Id in layout
|
||||
* @return the loaded text view
|
||||
*/
|
||||
private TextView getTextView(View view, int textResource) {
|
||||
TextView text = null;
|
||||
try {
|
||||
if (textResource == NO_RESOURCE && view instanceof TextView) {
|
||||
text = (TextView) view;
|
||||
}
|
||||
else if (textResource != NO_RESOURCE) {
|
||||
text = (TextView) view.findViewById(textResource);
|
||||
}
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
Log.e("AbstractWheelAdapter", "You must supply a resource ID for a TextView");
|
||||
throw new IllegalStateException("AbstractWheelAdapter requires the resource ID to be a TextView", e);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads view from resources
|
||||
* @param resource the resource Id
|
||||
* @return the loaded view or null if resource is not set
|
||||
*/
|
||||
private View getView(int resource, ViewGroup parent) {
|
||||
switch (resource) {
|
||||
case NO_RESOURCE:
|
||||
return null;
|
||||
case TEXT_VIEW_ITEM_RESOURCE:
|
||||
return new TextView(context);
|
||||
default:
|
||||
return inflater.inflate(resource, parent, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.lljjcoder.style.citypickerview.widget.wheel.WheelAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* Adapter class for old wheel adapter (deprecated WheelAdapter class).
|
||||
*
|
||||
* @deprecated Will be removed soon
|
||||
*/
|
||||
public class AdapterWheel extends AbstractWheelTextAdapter {
|
||||
|
||||
// Source adapter
|
||||
private WheelAdapter adapter;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
* @param adapter the source adapter
|
||||
*/
|
||||
public AdapterWheel(Context context, WheelAdapter adapter) {
|
||||
super(context);
|
||||
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets original adapter
|
||||
* @return the original adapter
|
||||
*/
|
||||
public WheelAdapter getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemsCount() {
|
||||
return adapter.getItemsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getItemText(int index) {
|
||||
return adapter.getItem(index);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The simple Array wheel adapter
|
||||
*
|
||||
* @param <T> the element type
|
||||
*/
|
||||
public class ArrayWheelAdapter<T> extends AbstractWheelTextAdapter {
|
||||
|
||||
// items
|
||||
private List<T> items;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context the current context
|
||||
* @param items the items
|
||||
*/
|
||||
public ArrayWheelAdapter(Context context, List<T> items) {
|
||||
super(context);
|
||||
|
||||
//setEmptyItemResource(TEXT_VIEW_ITEM_RESOURCE);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getItemText(int index) {
|
||||
if (index >= 0 && index < items.size()) {
|
||||
T item = items.get(index);
|
||||
if (item instanceof CharSequence) {
|
||||
return (CharSequence) item;
|
||||
}
|
||||
return item.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemsCount() {
|
||||
return items.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Numeric Wheel adapter.
|
||||
*/
|
||||
public class NumericWheelAdapter extends AbstractWheelTextAdapter {
|
||||
|
||||
/** The default min value */
|
||||
public static final int DEFAULT_MAX_VALUE = 9;
|
||||
|
||||
/** The default max value */
|
||||
private static final int DEFAULT_MIN_VALUE = 0;
|
||||
|
||||
// Values
|
||||
private int minValue;
|
||||
private int maxValue;
|
||||
|
||||
// format
|
||||
private String format;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
*/
|
||||
public NumericWheelAdapter(Context context) {
|
||||
this(context, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
* @param minValue the wheel min value
|
||||
* @param maxValue the wheel max value
|
||||
*/
|
||||
public NumericWheelAdapter(Context context, int minValue, int maxValue) {
|
||||
this(context, minValue, maxValue, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param context the current context
|
||||
* @param minValue the wheel min value
|
||||
* @param maxValue the wheel max value
|
||||
* @param format the format string
|
||||
*/
|
||||
public NumericWheelAdapter(Context context, int minValue, int maxValue, String format) {
|
||||
super(context);
|
||||
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getItemText(int index) {
|
||||
if (index >= 0 && index < getItemsCount()) {
|
||||
int value = minValue + index;
|
||||
return format != null ? String.format(format, value) : Integer.toString(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemsCount() {
|
||||
return maxValue - minValue + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2011 Yuri Kanivets
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.style.citypickerview.widget.wheel.adapters;
|
||||
|
||||
import android.database.DataSetObserver;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Wheel items adapter interface
|
||||
*/
|
||||
public interface WheelViewAdapter {
|
||||
/**
|
||||
* Gets items count
|
||||
* @return the count of wheel items
|
||||
*/
|
||||
public int getItemsCount();
|
||||
|
||||
/**
|
||||
* Get a View that displays the data at the specified position in the data set
|
||||
*
|
||||
* @param index the item index
|
||||
* @param convertView the old view to reuse if possible
|
||||
* @param parent the parent that this view will eventually be attached to
|
||||
* @return the wheel item View
|
||||
*/
|
||||
public View getItem(int index, View convertView, ViewGroup parent);
|
||||
|
||||
/**
|
||||
* Get a View that displays an empty wheel item placed before the first or after
|
||||
* the last wheel item.
|
||||
*
|
||||
* @param convertView the old view to reuse if possible
|
||||
* @param parent the parent that this view will eventually be attached to
|
||||
* @return the empty item View
|
||||
*/
|
||||
public View getEmptyItem(View convertView, ViewGroup parent);
|
||||
|
||||
/**
|
||||
* Register an observer that is called when changes happen to the data used by this adapter.
|
||||
* @param observer the observer to be registered
|
||||
*/
|
||||
public void registerDataSetObserver(DataSetObserver observer);
|
||||
|
||||
/**
|
||||
* Unregister an observer that has previously been registered
|
||||
* @param observer the observer to be unregistered
|
||||
*/
|
||||
void unregisterDataSetObserver(DataSetObserver observer);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.lljjcoder.style.citythreelist;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
import com.lljjcoder.widget.RecycleViewDividerForList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.citylist.utils.CityListLoader.BUNDATA;
|
||||
import static com.lljjcoder.style.citythreelist.ProvinceActivity.RESULT_DATA;
|
||||
|
||||
public class AreaActivity extends Activity {
|
||||
|
||||
private TextView mCityNameTv;
|
||||
|
||||
private ImageView mImgBack;
|
||||
|
||||
private RecyclerView mCityRecyclerView;
|
||||
|
||||
private CityInfoBean mProCityInfo = null;
|
||||
|
||||
private CityBean areaBean = new CityBean();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_citylist);
|
||||
mProCityInfo = this.getIntent().getParcelableExtra(BUNDATA);
|
||||
initView();
|
||||
|
||||
setData();
|
||||
|
||||
}
|
||||
|
||||
private void setData() {
|
||||
|
||||
if (mProCityInfo != null && mProCityInfo.getCityList().size() > 0) {
|
||||
mCityNameTv.setText("" + mProCityInfo.getName());
|
||||
|
||||
final List<CityInfoBean> cityList = mProCityInfo.getCityList();
|
||||
if (cityList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CityAdapter cityAdapter = new CityAdapter(AreaActivity.this, cityList);
|
||||
mCityRecyclerView.setAdapter(cityAdapter);
|
||||
cityAdapter.setOnItemClickListener(new CityAdapter.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(View view, int position) {
|
||||
|
||||
areaBean.setName(cityList.get(position).getName());
|
||||
areaBean.setId(cityList.get(position).getId());
|
||||
|
||||
//将计算的结果回传给第一个Activity
|
||||
Intent reReturnIntent = new Intent();
|
||||
reReturnIntent.putExtra("area", areaBean);
|
||||
setResult(RESULT_DATA, reReturnIntent);
|
||||
//退出第二个Activity
|
||||
AreaActivity.this.finish();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mImgBack = (ImageView) findViewById(R.id.img_left);
|
||||
mCityNameTv = (TextView) findViewById(R.id.cityname_tv);
|
||||
mImgBack.setVisibility(View.VISIBLE);
|
||||
mImgBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
mCityRecyclerView = (RecyclerView) findViewById(R.id.city_recyclerview);
|
||||
mCityRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
mCityRecyclerView.addItemDecoration(new RecycleViewDividerForList(this, LinearLayoutManager.HORIZONTAL, true));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.lljjcoder.style.citythreelist;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
import com.lljjcoder.widget.RecycleViewDividerForList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.citylist.utils.CityListLoader.BUNDATA;
|
||||
import static com.lljjcoder.style.citythreelist.ProvinceActivity.RESULT_DATA;
|
||||
|
||||
public class CityActivity extends Activity {
|
||||
|
||||
private TextView mCityNameTv;
|
||||
|
||||
private ImageView mImgBack;
|
||||
|
||||
private RecyclerView mCityRecyclerView;
|
||||
|
||||
private CityInfoBean mProInfo = null;
|
||||
|
||||
private String cityName = "";
|
||||
|
||||
private CityBean cityBean = new CityBean();
|
||||
|
||||
private CityBean area = new CityBean();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_citylist);
|
||||
mProInfo = this.getIntent().getParcelableExtra(BUNDATA);
|
||||
initView();
|
||||
|
||||
setData(mProInfo);
|
||||
|
||||
}
|
||||
|
||||
private void setData(CityInfoBean mProInfo) {
|
||||
|
||||
if (mProInfo != null && mProInfo.getCityList().size() > 0) {
|
||||
mCityNameTv.setText("" + mProInfo.getName());
|
||||
|
||||
final List<CityInfoBean> cityList = mProInfo.getCityList();
|
||||
if (cityList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CityAdapter cityAdapter = new CityAdapter(CityActivity.this, cityList);
|
||||
mCityRecyclerView.setAdapter(cityAdapter);
|
||||
cityAdapter.setOnItemClickListener(new CityAdapter.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(View view, int position) {
|
||||
|
||||
cityBean.setId(cityList.get(position).getId());
|
||||
cityBean.setName(cityList.get(position).getName());
|
||||
|
||||
Intent intent = new Intent(CityActivity.this, AreaActivity.class);
|
||||
intent.putExtra(BUNDATA, cityList.get(position));
|
||||
startActivityForResult(intent, RESULT_DATA);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mImgBack = (ImageView) findViewById(R.id.img_left);
|
||||
mCityNameTv = (TextView) findViewById(R.id.cityname_tv);
|
||||
mImgBack.setVisibility(View.VISIBLE);
|
||||
mImgBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
mCityNameTv = (TextView) findViewById(R.id.cityname_tv);
|
||||
mCityRecyclerView = (RecyclerView) findViewById(R.id.city_recyclerview);
|
||||
mCityRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
mCityRecyclerView.addItemDecoration(new RecycleViewDividerForList(this, LinearLayoutManager.HORIZONTAL, true));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_DATA && data != null) {
|
||||
area = data.getParcelableExtra("area");
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("city", cityBean);
|
||||
intent.putExtra("area", area);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.lljjcoder.style.citythreelist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/12/16 15:13
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityAdapter extends RecyclerView.Adapter<CityAdapter.MyViewHolder> {
|
||||
List<CityInfoBean> cityList = new ArrayList<>();
|
||||
|
||||
Context context;
|
||||
|
||||
private OnItemSelectedListener mOnItemClickListener;
|
||||
|
||||
public void setOnItemClickListener(OnItemSelectedListener onItemClickListener) {
|
||||
mOnItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
public interface OnItemSelectedListener {
|
||||
/**
|
||||
* item点击事件
|
||||
*
|
||||
* @param view
|
||||
* @param position
|
||||
*/
|
||||
void onItemSelected(View view, int position);
|
||||
}
|
||||
|
||||
public CityAdapter(Context context, List<CityInfoBean> cityList) {
|
||||
this.cityList = cityList;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
MyViewHolder holder = new MyViewHolder(
|
||||
LayoutInflater.from(context).inflate(R.layout.item_citylist, parent, false));
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(MyViewHolder holder, final int position) {
|
||||
holder.tv.setText(cityList.get(position).getName());
|
||||
holder.tv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mOnItemClickListener != null && position < cityList.size()) {
|
||||
mOnItemClickListener.onItemSelected(v, position);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cityList.size();
|
||||
}
|
||||
|
||||
class MyViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView tv;
|
||||
|
||||
public MyViewHolder(View view) {
|
||||
super(view);
|
||||
tv = (TextView) view.findViewById(R.id.default_item_city_name_tv);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.lljjcoder.style.citythreelist;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2018/3/20 10:57
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class CityBean implements Parcelable {
|
||||
private String id; /*110101*/
|
||||
|
||||
private String name; /*东城区*/
|
||||
|
||||
public String getId() {
|
||||
return id == null ? "" : id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? "" : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.name);
|
||||
}
|
||||
|
||||
public CityBean() {
|
||||
}
|
||||
|
||||
protected CityBean(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.name = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<CityBean> CREATOR = new Parcelable.Creator<CityBean>() {
|
||||
@Override
|
||||
public CityBean createFromParcel(Parcel source) {
|
||||
return new CityBean(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CityBean[] newArray(int size) {
|
||||
return new CityBean[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.lljjcoder.style.citythreelist;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.lljjcoder.style.citylist.bean.CityInfoBean;
|
||||
import com.lljjcoder.style.citylist.utils.CityListLoader;
|
||||
import com.lljjcoder.style.citypickerview.R;
|
||||
import com.lljjcoder.widget.RecycleViewDividerForList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.lljjcoder.style.citylist.utils.CityListLoader.BUNDATA;
|
||||
|
||||
public class ProvinceActivity extends Activity {
|
||||
|
||||
private TextView mCityNameTv;
|
||||
|
||||
private RecyclerView mCityRecyclerView;
|
||||
|
||||
public static final int RESULT_DATA = 1001;
|
||||
|
||||
private CityBean provinceBean = new CityBean();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_citylist);
|
||||
initView();
|
||||
setData();
|
||||
|
||||
}
|
||||
|
||||
private void setData() {
|
||||
|
||||
final List<CityInfoBean> cityList = CityListLoader.getInstance().getProListData();
|
||||
if (cityList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CityAdapter cityAdapter = new CityAdapter(ProvinceActivity.this, cityList);
|
||||
mCityRecyclerView.setAdapter(cityAdapter);
|
||||
cityAdapter.setOnItemClickListener(new CityAdapter.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(View view, int position) {
|
||||
|
||||
provinceBean.setId(cityList.get(position).getId());
|
||||
provinceBean.setName(cityList.get(position).getName());
|
||||
Intent intent = new Intent(ProvinceActivity.this, CityActivity.class);
|
||||
intent.putExtra(BUNDATA, cityList.get(position));
|
||||
startActivityForResult(intent, RESULT_DATA);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mCityNameTv = (TextView) findViewById(R.id.cityname_tv);
|
||||
mCityNameTv.setText("选择省份");
|
||||
mCityRecyclerView = (RecyclerView) findViewById(R.id.city_recyclerview);
|
||||
mCityRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
mCityRecyclerView.addItemDecoration(new RecycleViewDividerForList(this, LinearLayoutManager.HORIZONTAL, true));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == RESULT_DATA && data != null) {
|
||||
CityBean area = data.getParcelableExtra("area");
|
||||
CityBean city = data.getParcelableExtra("city");
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("province", provinceBean);
|
||||
intent.putExtra("city", city);
|
||||
intent.putExtra("area", area);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
77
citypickerview/src/main/java/com/lljjcoder/utils/utils.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package com.lljjcoder.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroupOverlay;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* 作者:liji on 2017/7/24 06:42
|
||||
* 邮箱:lijiwork@sina.com
|
||||
* QQ :275137657
|
||||
*/
|
||||
|
||||
public class utils {
|
||||
|
||||
String cityJsonStr = "";
|
||||
|
||||
//读取方法
|
||||
public static String getJson(Context context, String fileName) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
try {
|
||||
AssetManager assetManager = context.getAssets();
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open(fileName)));
|
||||
String line;
|
||||
while ((line = bf.readLine()) != null) {
|
||||
stringBuilder.append(line);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static void setBackgroundAlpha(Context mContext, float bgAlpha) {
|
||||
// WindowManager.LayoutParams lp = ((Activity) mContext).getWindow().getAttributes();
|
||||
// lp.alpha = bgAlpha;
|
||||
// ((Activity) mContext).getWindow().setAttributes(lp);
|
||||
|
||||
if (bgAlpha == 1f) {
|
||||
clearDim((Activity) mContext);
|
||||
}else{
|
||||
applyDim((Activity) mContext, bgAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyDim(Activity activity, float bgAlpha) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
ViewGroup parent = (ViewGroup) activity.getWindow().getDecorView().getRootView();
|
||||
//activity跟布局
|
||||
// ViewGroup parent = (ViewGroup) parent1.getChildAt(0);
|
||||
Drawable dim = new ColorDrawable(Color.BLACK);
|
||||
dim.setBounds(0, 0, parent.getWidth(), parent.getHeight());
|
||||
dim.setAlpha((int) (255 * bgAlpha));
|
||||
ViewGroupOverlay overlay = parent.getOverlay();
|
||||
overlay.add(dim);
|
||||
}
|
||||
}
|
||||
|
||||
private static void clearDim(Activity activity) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
ViewGroup parent = (ViewGroup) activity.getWindow().getDecorView().getRootView();
|
||||
//activity跟布局
|
||||
// ViewGroup parent = (ViewGroup) parent1.getChildAt(0);
|
||||
ViewGroupOverlay overlay = parent.getOverlay();
|
||||
overlay.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
*/
|
||||
|
||||
package com.lljjcoder.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* 说明:
|
||||
* 作者: fangkaijin on 2017/4/11.10:37
|
||||
* 邮箱:fangkaijin@gmail.com
|
||||
*/
|
||||
|
||||
public class RecycleViewDividerForList extends RecyclerView.ItemDecoration {
|
||||
|
||||
private Paint mPaint;
|
||||
|
||||
private Drawable mDivider;
|
||||
|
||||
private int mDividerHeight = 2;//分割线高度,默认为1px
|
||||
|
||||
private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
|
||||
|
||||
private static final int[] ATTRS = new int[] { android.R.attr.listDivider };
|
||||
|
||||
private boolean mLastLineShow = true;
|
||||
|
||||
/**
|
||||
* 默认分割线:高度为2px,颜色为灰色
|
||||
*
|
||||
* @param context
|
||||
* @param orientation 列表方向
|
||||
*/
|
||||
public RecycleViewDividerForList(Context context, int orientation) {
|
||||
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
|
||||
throw new IllegalArgumentException("请输入正确的参数!");
|
||||
}
|
||||
mOrientation = orientation;
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(ATTRS);
|
||||
mDivider = a.getDrawable(0);
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
public RecycleViewDividerForList(Context context, int orientation, boolean mLastLineShow) {
|
||||
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
|
||||
throw new IllegalArgumentException("请输入正确的参数!");
|
||||
}
|
||||
mOrientation = orientation;
|
||||
this.mLastLineShow = mLastLineShow;
|
||||
final TypedArray a = context.obtainStyledAttributes(ATTRS);
|
||||
mDivider = a.getDrawable(0);
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义分割线
|
||||
*
|
||||
* @param context
|
||||
* @param orientation 列表方向
|
||||
* @param drawableId 分割线图片
|
||||
*/
|
||||
public RecycleViewDividerForList(Context context, int orientation, int drawableId) {
|
||||
this(context, orientation);
|
||||
mDivider = ContextCompat.getDrawable(context, drawableId);
|
||||
mDividerHeight = mDivider.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义分割线
|
||||
*
|
||||
* @param context
|
||||
* @param orientation 列表方向
|
||||
* @param dividerHeight 分割线高度
|
||||
* @param dividerColor 分割线颜色
|
||||
*/
|
||||
public RecycleViewDividerForList(Context context, int orientation, int dividerHeight, int dividerColor) {
|
||||
this(context, orientation);
|
||||
mDividerHeight = dividerHeight;
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setColor(dividerColor);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
//获取分割线尺寸
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
outRect.set(0, 0, 0, mDividerHeight);
|
||||
}
|
||||
|
||||
//绘制分割线
|
||||
@Override
|
||||
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
||||
super.onDraw(c, parent, state);
|
||||
if (mOrientation == LinearLayoutManager.VERTICAL) {
|
||||
drawVertical(c, parent);
|
||||
}
|
||||
else {
|
||||
drawHorizontal(c, parent);
|
||||
}
|
||||
}
|
||||
|
||||
//绘制横向 item 分割线
|
||||
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
|
||||
final int left = parent.getPaddingLeft();
|
||||
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
|
||||
final int childSize = parent.getChildCount();
|
||||
for (int i = 0; i < childSize - (mLastLineShow ? 0 : 1); i++) {
|
||||
final View child = parent.getChildAt(i);
|
||||
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
final int top = child.getBottom() + layoutParams.bottomMargin;
|
||||
final int bottom = top + mDividerHeight;
|
||||
if (mDivider != null) {
|
||||
mDivider.setBounds(left, top, right, bottom);
|
||||
mDivider.draw(canvas);
|
||||
}
|
||||
if (mPaint != null) {
|
||||
canvas.drawRect(left, top, right, bottom, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//绘制纵向 item 分割线
|
||||
private void drawVertical(Canvas canvas, RecyclerView parent) {
|
||||
final int top = parent.getPaddingTop();
|
||||
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
|
||||
final int childSize = parent.getChildCount();
|
||||
for (int i = 0; i < childSize; i++) {
|
||||
final View child = parent.getChildAt(i);
|
||||
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
final int left = child.getRight() + layoutParams.rightMargin;
|
||||
final int right = left + mDividerHeight;
|
||||
if (mDivider != null) {
|
||||
mDivider.setBounds(left, top, right, bottom);
|
||||
mDivider.draw(canvas);
|
||||
}
|
||||
if (mPaint != null) {
|
||||
canvas.drawRect(left, top, right, bottom, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
citypickerview/src/main/res/anim/push_bottom_in.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 上下滑入式 -->
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<translate
|
||||
android:duration="200"
|
||||
android:fromYDelta="100%p"
|
||||
android:toYDelta="0"
|
||||
/>
|
||||
</set>
|
||||
10
citypickerview/src/main/res/anim/push_bottom_out.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 上下滑出式 -->
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
|
||||
<translate
|
||||
android:duration="200"
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="50%p" />
|
||||
</set>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@android:color/holo_red_light" android:state_enabled="false" />
|
||||
<item android:color="@android:color/black" android:state_enabled="true" />
|
||||
</selector>
|
||||
BIN
citypickerview/src/main/res/drawable-xhdpi/bar_back.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
citypickerview/src/main/res/drawable-xhdpi/ic_check.png
Normal file
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
BIN
citypickerview/src/main/res/drawable-xhdpi/ic_citypicker_ios.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
BIN
citypickerview/src/main/res/drawable-xhdpi/ic_close.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
citypickerview/src/main/res/drawable-xhdpi/input_close.png
Normal file
|
After Width: | Height: | Size: 566 B |
|
After Width: | Height: | Size: 598 B |
15
citypickerview/src/main/res/drawable/bg_draw1.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="@color/split_line_color" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- 主体背景颜色值 -->
|
||||
<item android:bottom="1px">
|
||||
<shape>
|
||||
<solid android:color="#ffffff" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
||||
6
citypickerview/src/main/res/drawable/bg_draw13.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:color="@color/split_line_color" android:width="1px"></stroke>
|
||||
<corners android:radius="2dp"></corners>
|
||||
</shape>
|
||||
6
citypickerview/src/main/res/drawable/bg_draw15.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:color="@color/split_line_color" android:width="1px"></stroke>
|
||||
<corners android:radius="3dp"></corners>
|
||||
</shape>
|
||||
8
citypickerview/src/main/res/drawable/bg_jd_picker.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<corners android:radius="20dp">
|
||||
|
||||
</corners>
|
||||
|
||||
<solid android:color="#ff40c2fc"></solid>
|
||||
</shape>
|
||||
8
citypickerview/src/main/res/drawable/circle_text.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
android:useLevel="false" >
|
||||
<solid android:color="#ff000000" />
|
||||
<corners android:radius="6dp" ></corners>
|
||||
</shape>
|
||||
5
citypickerview/src/main/res/drawable/city_bg_l.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/split_line_bootom_color" android:state_pressed="true"></item>
|
||||
<item android:drawable="@color/white" android:state_pressed="false"></item>
|
||||
</selector>
|
||||
6
citypickerview/src/main/res/drawable/cityitem_click.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@color/sort_catagory" android:state_pressed="true"/>
|
||||
<item android:drawable="@color/white" android:state_pressed="false"/>
|
||||
</selector>
|
||||
5
citypickerview/src/main/res/drawable/edittext_bg.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_window_focused="false" android:drawable="@drawable/edittext_normal" />
|
||||
<item android:state_focused="true" android:drawable="@drawable/edittext_focused" />
|
||||
</selector>
|
||||
16
citypickerview/src/main/res/drawable/edittext_focused.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
~ Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
~ Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
~ Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
~ Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/white" />
|
||||
<corners android:radius="2dp"/>
|
||||
<stroke
|
||||
android:width="2px"
|
||||
android:color="@color/colorPrimary" />
|
||||
</shape>
|
||||
16
citypickerview/src/main/res/drawable/edittext_normal.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
~ Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||
~ Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||
~ Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||
~ Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/white" />
|
||||
<corners android:radius="2dp"/>
|
||||
<stroke
|
||||
android:width="1px"
|
||||
android:color="@color/input_stock" />
|
||||
</shape>
|
||||
11
citypickerview/src/main/res/drawable/sidebar_background.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient android:startColor="#00000000" android:endColor="#00000000" android:angle="90.0" />
|
||||
|
||||
<corners
|
||||
android:topLeftRadius="8dip"
|
||||
android:bottomLeftRadius="8dip"/>
|
||||
|
||||
</shape>
|
||||
|
||||
5
citypickerview/src/main/res/drawable/test_wheel_bg.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<solid android:color="@color/liji_c_blue"></solid>
|
||||
</shape>
|
||||
23
citypickerview/src/main/res/drawable/wheel_bg.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Android Wheel Control.
|
||||
http://android-devblog.blogspot.com/2010/05/wheel-ui-contol.html
|
||||
|
||||
Copyright 2010 Yuri Kanivets
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</layer-list>
|
||||
31
citypickerview/src/main/res/drawable/wheel_val.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Android Wheel Control.
|
||||
http://android-devblog.blogspot.com/2010/05/wheel-ui-contol.html
|
||||
|
||||
Copyright 2010 Yuri Kanivets
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!--
|
||||
<gradient
|
||||
android:startColor="#70222222"
|
||||
android:centerColor="#70222222"
|
||||
android:endColor="#70EEEEEE"
|
||||
android:angle="90" />
|
||||
-->
|
||||
|
||||
<stroke android:width="1dp" android:color="#C7C7C7" />
|
||||
</shape>
|
||||
171
citypickerview/src/main/res/layout/activity_city_list_select.xml
Normal file
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#ffffff"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:background="#ff40c2fc"
|
||||
android:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgBack"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@drawable/bar_back"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="城市选择"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:padding="5dp">
|
||||
|
||||
<com.lljjcoder.style.citylist.widget.CleanableEditView
|
||||
android:id="@+id/cityInputText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:drawableLeft="@drawable/search_bar_icon_normal"
|
||||
android:drawablePadding="5dp"
|
||||
android:drawableRight="@drawable/input_close"
|
||||
android:gravity="left|center_vertical"
|
||||
android:hint="请输入城市"
|
||||
android:padding="10dp"
|
||||
android:textColor="@color/color_text_02"
|
||||
android:textColorHint="@color/color_text_01"
|
||||
android:textSize="14sp"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:background="@drawable/bg_draw1"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/currentCityTag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="当前城市"
|
||||
android:textColor="@color/text_color_02"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/currentCity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_toRightOf="@+id/currentCityTag"
|
||||
android:ellipsize="none"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_color_02"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/sort_catagory"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="15dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="15dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/localCityTag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="定位城市"
|
||||
android:textColor="@color/text_color_02"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/localCity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_toRightOf="@+id/localCityTag"
|
||||
android:background="@drawable/bg_draw13"
|
||||
android:ellipsize="middle"
|
||||
android:gravity="center"
|
||||
android:maxLength="4"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:textColor="@color/text_color_02"
|
||||
android:textSize="12sp"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/country_lvcountry"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:divider="@color/split_line_color"
|
||||
android:dividerHeight="1px"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/bg_draw15"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/text_color_02"
|
||||
android:textSize="20sp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.lljjcoder.style.citylist.sortlistview.SideBar
|
||||
android:id="@+id/sidrbar"
|
||||
android:layout_width="30.0dip"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="right|center"/>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
43
citypickerview/src/main/res/layout/activity_citylist.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?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:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="45dp"
|
||||
android:background="#ff40c2fc">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_left"
|
||||
android:layout_width="9dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@drawable/ic_citypicker_bar_back"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cityname_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="选择省份"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/city_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
android:dividerHeight="10dp"/>
|
||||
</LinearLayout>
|
||||
16
citypickerview/src/main/res/layout/default_item_city.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/default_item_city_name_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/white"
|
||||
android:layout_height="30dp"
|
||||
android:gravity="center"
|
||||
android:textSize="14sp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
26
citypickerview/src/main/res/layout/dialog_alarm_ui.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:theme="@android:style/Theme.Translucent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noticeText"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="TextView"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:background="@drawable/circle_text"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:singleLine="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
16
citypickerview/src/main/res/layout/item_citylist.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/default_item_city_name_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:background="@color/white"
|
||||
android:gravity="center"
|
||||
android:textSize="14sp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
83
citypickerview/src/main/res/layout/pop_citypicker.xml
Normal file
@@ -0,0 +1,83 @@
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/ll_title_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="#E9E9E9"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:background="@color/province_line_border">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_confirm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginRight="15dp"
|
||||
android:gravity="center_vertical"
|
||||
android:text="确定"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:gravity="center_vertical"
|
||||
android:text="选择地区"
|
||||
android:textColor="#000000"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:gravity="center_vertical"
|
||||
android:text="取消"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_title"
|
||||
android:layout_width="fill_parent"
|
||||
android:background="@color/white"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.lljjcoder.style.citypickerview.widget.wheel.WheelView
|
||||
android:id="@+id/id_province"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
</com.lljjcoder.style.citypickerview.widget.wheel.WheelView>
|
||||
|
||||
<com.lljjcoder.style.citypickerview.widget.wheel.WheelView
|
||||
android:id="@+id/id_city"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
</com.lljjcoder.style.citypickerview.widget.wheel.WheelView>
|
||||
|
||||
<com.lljjcoder.style.citypickerview.widget.wheel.WheelView
|
||||
android:id="@+id/id_district"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
</com.lljjcoder.style.citypickerview.widget.wheel.WheelView>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
98
citypickerview/src/main/res/layout/pop_jdcitypicker.xml
Normal file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="400dp"
|
||||
android:background="#E9E9E9"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="400dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/white">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="请选择"
|
||||
android:textColor="@color/color_text_03"
|
||||
android:textSize="14sp" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close_img"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="15dp"
|
||||
android:background="@drawable/ic_close" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="#e8e8e8" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="41dp"
|
||||
android:background="@color/white">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/choose_tab"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/province_tv"
|
||||
style="@style/tab"
|
||||
android:text="请选择" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/city_tv"
|
||||
style="@style/tab" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/area_tv"
|
||||
style="@style/tab" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/selected_line"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_below="@+id/choose_tab"
|
||||
android:background="@android:color/holo_red_light" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#e8e8e8" />
|
||||
|
||||
<com.lljjcoder.style.cityjd.MyListView
|
||||
android:id="@+id/city_listview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
android:divider="@null" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
29
citypickerview/src/main/res/layout/pop_jdcitypicker_item.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/selector_text_color_tab"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/selectImg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_toEndOf="@+id/name"
|
||||
android:layout_toRightOf="@+id/name"
|
||||
android:src="@drawable/ic_check"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
31
citypickerview/src/main/res/layout/sortlistview_item.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/cityitem_click"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/catalog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="#ff40c2fc"
|
||||
android:padding="10dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="10dp"
|
||||
android:textColor="@color/text_color_02"
|
||||
android:textSize="16sp"
|
||||
/>
|
||||
</LinearLayout>
|
||||
6
citypickerview/src/main/res/values-w820dp/dimens.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
||||
13
citypickerview/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="CityPickerView">
|
||||
<attr name="citypicker_title_background" format="color"></attr><!--标题背景颜色-->
|
||||
<attr name="citypicker_text_confirm_color" format="color"></attr><!--确认文字的颜色-->
|
||||
<attr name="citypicker_text_cancel_color" format="color"></attr><!--取消文字的颜色-->
|
||||
<attr name="citypicker_wheel_color" format="color"></attr><!--滚轮的颜色-->
|
||||
<attr name="citypicker_wheel_text_color" format="color"></attr><!--滚轮里面内容的文字颜色-->
|
||||
<attr name="citypicker_wheel_text_size" format="dimension"></attr><!--滚轮里面内容的文字大小-->
|
||||
<attr name="citypicker_title_text_size" format="dimension"></attr><!--标题的文字大小-->
|
||||
<attr name="citypicker_title_action_size" format="dimension"></attr><!--确认和取消的文字大小-->
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
29
citypickerview/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#ff40c2fc</color>
|
||||
<color name="colorPrimaryDark">#ff08a7ee</color>
|
||||
<color name="colorAccent">#ff75d1fa</color>
|
||||
<color name="activity_bg">#ffe7e7e7</color>
|
||||
<color name="color_text_01">#ffc5c9ce</color>
|
||||
<color name="color_text_03">#ffb1b7be</color>
|
||||
<color name="split_line_color">#ffc9d1d9</color>
|
||||
<color name="split_line_bootom_color">#ffa8adb3</color>
|
||||
<color name="input_stock">#ffbdc7d8</color>
|
||||
<color name="color_text_02">#ff181c20</color>
|
||||
<color name="location_circle_bg">#320483b9</color>
|
||||
<color name="indicator_color">#fffff18f</color>
|
||||
<color name="tabs_click">#ff8a153e</color>
|
||||
<color name="bank_bg01">#ff002142</color>
|
||||
<color name="bank_bg02">#ffe2607b</color>
|
||||
<color name="bank_FF6C6C6C">#FF6C6C6C</color>
|
||||
<color name="text_color_02">#FF6C6C6C</color>
|
||||
<color name="sort_catagory">#FFE0E0E0</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
|
||||
<color name="province_line_border">#C7C7C7</color>
|
||||
<color name="liji_c_blue">#26A5FF</color>
|
||||
<color name="liji_material_blue_500">#03a9f4</color>
|
||||
<color name="liji_material_blue_700">#0288d1</color>
|
||||
<color name="liji_material_red_500">#e51c23</color>
|
||||
<color name="liji_material_red_700">#d01716</color>
|
||||
</resources>
|
||||
5
citypickerview/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
3
citypickerview/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">CityPicker</string>
|
||||
</resources>
|
||||
28
citypickerview/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AnimBottom" parent="@android:style/Animation">
|
||||
<item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
|
||||
<item name="android:windowExitAnimation">@anim/push_bottom_out</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="tab">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
<item name="android:maxLines">1</item>
|
||||
<item name="android:padding">10dp</item>
|
||||
<item name="android:textColor">@color/color_text_02</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:visibility">visible</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
7
citypickerview/src/main/res/xml/provider_paths.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- /storage/emulated/0/Download/com.bugly.upgrade.demo/.beta/apk-->
|
||||
<external-path name="beta_external_path" path="Download/"/>
|
||||
<!--/storage/emulated/0/Android/data/com.bugly.upgrade.demo/files/apk/-->
|
||||
<external-path name="beta_external_files_path" path="Android/data/"/>
|
||||
</paths>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.lljjcoder.style.citypickerview;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* To work on unit tests, switch the Test Artifact in the Build Variants view.
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||