Initial commit
This commit is contained in:
2
library/WheelPicker/.gitignore
vendored
Normal file
2
library/WheelPicker/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/*.iml
|
||||
11
library/WheelPicker/build.gradle
Normal file
11
library/WheelPicker/build.gradle
Normal file
@@ -0,0 +1,11 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
ext {
|
||||
isLibrary = true
|
||||
pomArtifactId = "WheelPicker"
|
||||
pomDescription = "wheel picker for android, include date picker, time picker, option picker, address picker, etc."
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":library:Common")
|
||||
}
|
||||
2
library/WheelPicker/src/main/AndroidManifest.xml
Normal file
2
library/WheelPicker/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="cn.qqtheme.framework.wheelpicker" />
|
||||
@@ -0,0 +1,358 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import cn.qqtheme.framework.util.LogUtils;
|
||||
import cn.qqtheme.framework.widget.WheelView;
|
||||
|
||||
/**
|
||||
* 地址选择器(包括省级、地级、县级)。
|
||||
* 地址数据见示例项目的“city.json”,来源于国家统计局官网(http://www.stats.gov.cn/tjsj/tjbz/xzqhdm)
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/15
|
||||
*/
|
||||
public class AddressPicker extends WheelPicker {
|
||||
private ArrayList<String> provinceList = new ArrayList<String>();
|
||||
private ArrayList<ArrayList<String>> cityList = new ArrayList<ArrayList<String>>();
|
||||
private ArrayList<ArrayList<ArrayList<String>>> countyList = new ArrayList<ArrayList<ArrayList<String>>>();
|
||||
private OnAddressPickListener onAddressPickListener;
|
||||
private String selectedProvince = "", selectedCity = "", selectedCounty = "";
|
||||
private int selectedProvinceIndex = 0, selectedCityIndex = 0, selectedCountyIndex = 0;
|
||||
private boolean hideProvince = false;
|
||||
private boolean hideCounty = false;
|
||||
|
||||
/**
|
||||
* Instantiates a new Address picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
* @param data the data
|
||||
*/
|
||||
public AddressPicker(Activity activity, ArrayList<Province> data) {
|
||||
super(activity);
|
||||
int provinceSize = data.size();
|
||||
//添加省
|
||||
for (int x = 0; x < provinceSize; x++) {
|
||||
Province pro = data.get(x);
|
||||
provinceList.add(pro.getAreaName());
|
||||
ArrayList<City> cities = pro.getCities();
|
||||
ArrayList<String> xCities = new ArrayList<String>();
|
||||
ArrayList<ArrayList<String>> xCounties = new ArrayList<ArrayList<String>>();
|
||||
int citySize = cities.size();
|
||||
//添加地市
|
||||
for (int y = 0; y < citySize; y++) {
|
||||
City cit = cities.get(y);
|
||||
xCities.add(cit.getAreaName());
|
||||
ArrayList<County> counties = cit.getCounties();
|
||||
ArrayList<String> yCounties = new ArrayList<String>();
|
||||
int countySize = counties.size();
|
||||
//添加区县
|
||||
if (countySize == 0) {
|
||||
yCounties.add(cit.getAreaName());
|
||||
} else {
|
||||
for (int z = 0; z < countySize; z++) {
|
||||
yCounties.add(counties.get(z).getAreaName());
|
||||
}
|
||||
}
|
||||
xCounties.add(yCounties);
|
||||
}
|
||||
cityList.add(xCities);
|
||||
countyList.add(xCounties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param province the province
|
||||
* @param city the city
|
||||
* @param county the county
|
||||
*/
|
||||
public void setSelectedItem(String province, String city, String county) {
|
||||
for (int i = 0; i < provinceList.size(); i++) {
|
||||
String pro = provinceList.get(i);
|
||||
if (pro.contains(province)) {
|
||||
selectedProvinceIndex = i;
|
||||
LogUtils.debug("init select province: " + pro);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ArrayList<String> cities = cityList.get(selectedProvinceIndex);
|
||||
for (int j = 0; j < cities.size(); j++) {
|
||||
String cit = cities.get(j);
|
||||
if (cit.contains(city)) {
|
||||
selectedCityIndex = j;
|
||||
LogUtils.debug("init select city: " + cit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ArrayList<String> counties = countyList.get(selectedProvinceIndex).get(selectedCityIndex);
|
||||
for (int k = 0; k < counties.size(); k++) {
|
||||
String cou = counties.get(k);
|
||||
if (cou.contains(county)) {
|
||||
selectedCountyIndex = k;
|
||||
LogUtils.debug("init select county: " + cou);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LogUtils.debug(String.format("init select index: %s-%s-%s", selectedProvinceIndex, selectedCityIndex, selectedCountyIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏省级行政区,只显示地市级和区县级。
|
||||
* 设置为true的话,地址数据中只需要某个省份的即可
|
||||
* 参见示例中的“city2.json”
|
||||
*
|
||||
* @param hideProvince the hide province
|
||||
*/
|
||||
public void setHideProvince(boolean hideProvince) {
|
||||
this.hideProvince = hideProvince;
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏县级行政区,只显示省级和市级。
|
||||
* 设置为true的话,hideProvince将强制为false
|
||||
* 数据源依然使用“city.json” 仅在逻辑上隐藏县级选择框。
|
||||
*
|
||||
* @param hideCounty the hide county
|
||||
*/
|
||||
public void setHideCounty(boolean hideCounty) {
|
||||
this.hideCounty = hideCounty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on address pick listener.
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void setOnAddressPickListener(OnAddressPickListener listener) {
|
||||
this.onAddressPickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected View makeCenterView() {
|
||||
if (hideCounty) {
|
||||
hideProvince = false;
|
||||
}
|
||||
if (provinceList.size() == 0) {
|
||||
throw new IllegalArgumentException("please initial options at first, can't be empty");
|
||||
}
|
||||
LinearLayout layout = new LinearLayout(activity);
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setGravity(Gravity.CENTER);
|
||||
final WheelView provinceView = new WheelView(activity);
|
||||
provinceView.setLayoutParams(new LinearLayout.LayoutParams(screenWidthPixels / 3, WRAP_CONTENT));
|
||||
provinceView.setTextSize(textSize);
|
||||
provinceView.setTextColor(textColorNormal, textColorFocus);
|
||||
provinceView.setLineVisible(lineVisible);
|
||||
provinceView.setLineColor(lineColor);
|
||||
provinceView.setOffset(offset);
|
||||
layout.addView(provinceView);
|
||||
if (hideProvince) {
|
||||
provinceView.setVisibility(View.GONE);
|
||||
}
|
||||
final WheelView cityView = new WheelView(activity);
|
||||
cityView.setLayoutParams(new LinearLayout.LayoutParams(screenWidthPixels / 3, WRAP_CONTENT));
|
||||
cityView.setTextSize(textSize);
|
||||
cityView.setTextColor(textColorNormal, textColorFocus);
|
||||
cityView.setLineVisible(lineVisible);
|
||||
cityView.setLineColor(lineColor);
|
||||
cityView.setOffset(offset);
|
||||
layout.addView(cityView);
|
||||
final WheelView countyView = new WheelView(activity);
|
||||
countyView.setLayoutParams(new LinearLayout.LayoutParams(screenWidthPixels / 3, WRAP_CONTENT));
|
||||
countyView.setTextSize(textSize);
|
||||
countyView.setTextColor(textColorNormal, textColorFocus);
|
||||
countyView.setLineVisible(lineVisible);
|
||||
countyView.setLineColor(lineColor);
|
||||
countyView.setOffset(offset);
|
||||
layout.addView(countyView);
|
||||
if (hideCounty) {
|
||||
countyView.setVisibility(View.GONE);
|
||||
}
|
||||
provinceView.setItems(provinceList, selectedProvinceIndex);
|
||||
provinceView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedProvince = item;
|
||||
selectedProvinceIndex = selectedIndex;
|
||||
selectedCountyIndex = 0;
|
||||
//根据省份获取地市
|
||||
cityView.setItems(cityList.get(selectedProvinceIndex), isUserScroll ? 0 : selectedCityIndex);
|
||||
//根据地市获取区县
|
||||
countyView.setItems(countyList.get(selectedProvinceIndex).get(0), isUserScroll ? 0 : selectedCountyIndex);
|
||||
}
|
||||
});
|
||||
cityView.setItems(cityList.get(selectedProvinceIndex), selectedCityIndex);
|
||||
cityView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedCity = item;
|
||||
selectedCityIndex = selectedIndex;
|
||||
//根据地市获取区县
|
||||
countyView.setItems(countyList.get(selectedProvinceIndex).get(selectedCityIndex), isUserScroll ? 0 : selectedCountyIndex);
|
||||
}
|
||||
});
|
||||
countyView.setItems(countyList.get(selectedProvinceIndex).get(selectedCityIndex), selectedCountyIndex);
|
||||
countyView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedCounty = item;
|
||||
selectedCountyIndex = selectedIndex;
|
||||
}
|
||||
});
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubmit() {
|
||||
if (onAddressPickListener != null) {
|
||||
if (hideCounty) {
|
||||
onAddressPickListener.onAddressPicked(selectedProvince, selectedCity, null);
|
||||
} else {
|
||||
onAddressPickListener.onAddressPicked(selectedProvince, selectedCity, selectedCounty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On address pick listener.
|
||||
*/
|
||||
public interface OnAddressPickListener {
|
||||
|
||||
/**
|
||||
* On address picked.
|
||||
*
|
||||
* @param province the province
|
||||
* @param city the city
|
||||
* @param county the county ,if {@hideCounty} is true,this is null
|
||||
*/
|
||||
void onAddressPicked(String province, String city, String county);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Area.
|
||||
*/
|
||||
public abstract static class Area {
|
||||
/**
|
||||
* The Area id.
|
||||
*/
|
||||
String areaId;
|
||||
/**
|
||||
* The Area name.
|
||||
*/
|
||||
String areaName;
|
||||
|
||||
/**
|
||||
* Gets area id.
|
||||
*
|
||||
* @return the area id
|
||||
*/
|
||||
public String getAreaId() {
|
||||
return areaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets area id.
|
||||
*
|
||||
* @param areaId the area id
|
||||
*/
|
||||
public void setAreaId(String areaId) {
|
||||
this.areaId = areaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets area name.
|
||||
*
|
||||
* @return the area name
|
||||
*/
|
||||
public String getAreaName() {
|
||||
return areaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets area name.
|
||||
*
|
||||
* @param areaName the area name
|
||||
*/
|
||||
public void setAreaName(String areaName) {
|
||||
this.areaName = areaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "areaId=" + areaId + ",areaName=" + areaName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Province.
|
||||
*/
|
||||
public static class Province extends Area {
|
||||
/**
|
||||
* The Cities.
|
||||
*/
|
||||
ArrayList<City> cities = new ArrayList<City>();
|
||||
|
||||
/**
|
||||
* Gets cities.
|
||||
*
|
||||
* @return the cities
|
||||
*/
|
||||
public ArrayList<City> getCities() {
|
||||
return cities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cities.
|
||||
*
|
||||
* @param cities the cities
|
||||
*/
|
||||
public void setCities(ArrayList<City> cities) {
|
||||
this.cities = cities;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type City.
|
||||
*/
|
||||
public static class City extends Area {
|
||||
private ArrayList<County> counties = new ArrayList<County>();
|
||||
|
||||
/**
|
||||
* Gets counties.
|
||||
*
|
||||
* @return the counties
|
||||
*/
|
||||
public ArrayList<County> getCounties() {
|
||||
return counties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets counties.
|
||||
*
|
||||
* @param counties the counties
|
||||
*/
|
||||
public void setCounties(ArrayList<County> counties) {
|
||||
this.counties = counties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type County.
|
||||
*/
|
||||
public static class County extends Area {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
/**
|
||||
* 生肖选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/15
|
||||
*/
|
||||
public class ChineseZodiacPicker extends OptionPicker {
|
||||
|
||||
/**
|
||||
* Instantiates a new Chinese zodiac picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public ChineseZodiacPicker(Activity activity) {
|
||||
super(activity, new String[]{
|
||||
"鼠",
|
||||
"牛",
|
||||
"虎",
|
||||
"兔",
|
||||
"龙",
|
||||
"蛇",
|
||||
"马",
|
||||
"羊",
|
||||
"猴",
|
||||
"鸡",
|
||||
"狗",
|
||||
"猪",
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
/**
|
||||
* 星座选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/15
|
||||
*/
|
||||
public class ConstellationPicker extends OptionPicker {
|
||||
|
||||
/**
|
||||
* Instantiates a new Constellation picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public ConstellationPicker(Activity activity) {
|
||||
super(activity, new String[]{
|
||||
"水瓶",
|
||||
"双鱼",
|
||||
"白羊",
|
||||
"金牛",
|
||||
"双子",
|
||||
"巨蟹",
|
||||
"狮子",
|
||||
"处女",
|
||||
"天秤",
|
||||
"天蝎",
|
||||
"射手",
|
||||
"摩羯",
|
||||
});
|
||||
setLabel("座");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import cn.qqtheme.framework.util.DateUtils;
|
||||
import cn.qqtheme.framework.widget.WheelView;
|
||||
|
||||
/**
|
||||
* 日期选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/14
|
||||
*/
|
||||
public class DatePicker extends WheelPicker {
|
||||
/**
|
||||
* 年月日
|
||||
*/
|
||||
public static final int YEAR_MONTH_DAY = 0;
|
||||
/**
|
||||
* 年月
|
||||
*/
|
||||
public static final int YEAR_MONTH = 1;
|
||||
/**
|
||||
* 月日
|
||||
*/
|
||||
public static final int MONTH_DAY = 2;
|
||||
private ArrayList<String> years = new ArrayList<String>();
|
||||
private ArrayList<String> months = new ArrayList<String>();
|
||||
private ArrayList<String> days = new ArrayList<String>();
|
||||
private OnDatePickListener onDatePickListener;
|
||||
private String yearLabel = "年", monthLabel = "月", dayLabel = "日";
|
||||
private int selectedYearIndex = 0, selectedMonthIndex = 0, selectedDayIndex = 0;
|
||||
private int mode = YEAR_MONTH_DAY;
|
||||
|
||||
/**
|
||||
* 安卓开发应避免使用枚举类(enum),因为相比于静态常量enum会花费两倍以上的内存。
|
||||
*
|
||||
* @link http ://developer.android.com/training/articles/memory.html#Overhead
|
||||
*/
|
||||
@IntDef(flag = false, value = {YEAR_MONTH_DAY, YEAR_MONTH, MONTH_DAY})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Mode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Date picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public DatePicker(Activity activity) {
|
||||
this(activity, YEAR_MONTH_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Date picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
* @param mode the mode
|
||||
* @see #YEAR_MONTH_DAY #YEAR_MONTH_DAY#YEAR_MONTH_DAY
|
||||
* @see #YEAR_MONTH #YEAR_MONTH#YEAR_MONTH
|
||||
* @see #MONTH_DAY #MONTH_DAY#MONTH_DAY
|
||||
*/
|
||||
public DatePicker(Activity activity, @Mode int mode) {
|
||||
super(activity);
|
||||
this.mode = mode;
|
||||
for (int i = 2000; i <= 2050; i++) {
|
||||
years.add(String.valueOf(i));
|
||||
}
|
||||
for (int i = 1; i <= 12; i++) {
|
||||
months.add(DateUtils.fillZero(i));
|
||||
}
|
||||
for (int i = 1; i <= 31; i++) {
|
||||
days.add(DateUtils.fillZero(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets label.
|
||||
*
|
||||
* @param yearLabel the year label
|
||||
* @param monthLabel the month label
|
||||
* @param dayLabel the day label
|
||||
*/
|
||||
public void setLabel(String yearLabel, String monthLabel, String dayLabel) {
|
||||
this.yearLabel = yearLabel;
|
||||
this.monthLabel = monthLabel;
|
||||
this.dayLabel = dayLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets range.
|
||||
*
|
||||
* @param startYear the start year
|
||||
* @param endYear the end year
|
||||
*/
|
||||
public void setRange(int startYear, int endYear) {
|
||||
years.clear();
|
||||
for (int i = startYear; i <= endYear; i++) {
|
||||
years.add(String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
private int findItemIndex(ArrayList<String> items, int item) {
|
||||
//折半查找有序元素的索引
|
||||
int index = Collections.binarySearch(items, item, new Comparator<Object>() {
|
||||
@Override
|
||||
public int compare(Object lhs, Object rhs) {
|
||||
String lhsStr = lhs.toString();
|
||||
String rhsStr = rhs.toString();
|
||||
lhsStr = lhsStr.startsWith("0") ? lhsStr.substring(1) : lhsStr;
|
||||
rhsStr = rhsStr.startsWith("0") ? rhsStr.substring(1) : rhsStr;
|
||||
return Integer.parseInt(lhsStr) - Integer.parseInt(rhsStr);
|
||||
}
|
||||
});
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param year the year
|
||||
* @param month the month
|
||||
* @param day the day
|
||||
*/
|
||||
public void setSelectedItem(int year, int month, int day) {
|
||||
selectedYearIndex = findItemIndex(years, year);
|
||||
selectedMonthIndex = findItemIndex(months, month);
|
||||
selectedDayIndex = findItemIndex(days, day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param yearOrMonth the year or month
|
||||
* @param monthOrDay the month or day
|
||||
*/
|
||||
public void setSelectedItem(int yearOrMonth, int monthOrDay) {
|
||||
if (mode == MONTH_DAY) {
|
||||
selectedMonthIndex = findItemIndex(months, yearOrMonth);
|
||||
selectedDayIndex = findItemIndex(days, monthOrDay);
|
||||
} else {
|
||||
selectedYearIndex = findItemIndex(years, yearOrMonth);
|
||||
selectedMonthIndex = findItemIndex(months, monthOrDay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on date pick listener.
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void setOnDatePickListener(OnDatePickListener listener) {
|
||||
this.onDatePickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected View makeCenterView() {
|
||||
LinearLayout layout = new LinearLayout(activity);
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setGravity(Gravity.CENTER);
|
||||
WheelView yearView = new WheelView(activity);
|
||||
yearView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
yearView.setTextSize(textSize);
|
||||
yearView.setTextColor(textColorNormal, textColorFocus);
|
||||
yearView.setLineVisible(lineVisible);
|
||||
yearView.setLineColor(lineColor);
|
||||
yearView.setOffset(offset);
|
||||
layout.addView(yearView);
|
||||
TextView yearTextView = new TextView(activity);
|
||||
yearTextView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
yearTextView.setTextSize(textSize);
|
||||
yearTextView.setTextColor(textColorFocus);
|
||||
if (!TextUtils.isEmpty(yearLabel)) {
|
||||
yearTextView.setText(yearLabel);
|
||||
}
|
||||
layout.addView(yearTextView);
|
||||
WheelView monthView = new WheelView(activity);
|
||||
monthView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
monthView.setTextSize(textSize);
|
||||
monthView.setTextColor(textColorNormal, textColorFocus);
|
||||
monthView.setLineVisible(lineVisible);
|
||||
monthView.setLineColor(lineColor);
|
||||
monthView.setOffset(offset);
|
||||
layout.addView(monthView);
|
||||
TextView monthTextView = new TextView(activity);
|
||||
monthTextView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
monthTextView.setTextSize(textSize);
|
||||
monthTextView.setTextColor(textColorFocus);
|
||||
if (!TextUtils.isEmpty(monthLabel)) {
|
||||
monthTextView.setText(monthLabel);
|
||||
}
|
||||
layout.addView(monthTextView);
|
||||
final WheelView dayView = new WheelView(activity);
|
||||
dayView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
dayView.setTextSize(textSize);
|
||||
dayView.setTextColor(textColorNormal, textColorFocus);
|
||||
dayView.setLineVisible(lineVisible);
|
||||
dayView.setLineColor(lineColor);
|
||||
dayView.setOffset(offset);
|
||||
layout.addView(dayView);
|
||||
TextView dayTextView = new TextView(activity);
|
||||
dayTextView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
dayTextView.setTextSize(textSize);
|
||||
dayTextView.setTextColor(textColorFocus);
|
||||
if (!TextUtils.isEmpty(dayLabel)) {
|
||||
dayTextView.setText(dayLabel);
|
||||
}
|
||||
layout.addView(dayTextView);
|
||||
if (mode == YEAR_MONTH) {
|
||||
dayView.setVisibility(View.GONE);
|
||||
dayTextView.setVisibility(View.GONE);
|
||||
} else if (mode == MONTH_DAY) {
|
||||
yearView.setVisibility(View.GONE);
|
||||
yearTextView.setVisibility(View.GONE);
|
||||
}
|
||||
if (mode != MONTH_DAY) {
|
||||
if (!TextUtils.isEmpty(yearLabel)) {
|
||||
yearTextView.setText(yearLabel);
|
||||
}
|
||||
if (selectedYearIndex == 0) {
|
||||
yearView.setItems(years);
|
||||
} else {
|
||||
yearView.setItems(years, selectedYearIndex);
|
||||
}
|
||||
yearView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedYearIndex = selectedIndex;
|
||||
//需要根据年份及月份动态计算天数
|
||||
days.clear();
|
||||
int maxDays = DateUtils.calculateDaysInMonth(stringToYearMonthDay(item), stringToYearMonthDay(months.get(selectedMonthIndex)));
|
||||
for (int i = 1; i <= maxDays; i++) {
|
||||
days.add(DateUtils.fillZero(i));
|
||||
}
|
||||
if (selectedDayIndex >= maxDays) {
|
||||
//年或月变动时,保持之前选择的日不动:如果之前选择的日是之前年月的最大日,则日自动为该年月的最大日
|
||||
selectedDayIndex = days.size() - 1;
|
||||
}
|
||||
dayView.setItems(days, selectedDayIndex);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!TextUtils.isEmpty(monthLabel)) {
|
||||
monthTextView.setText(monthLabel);
|
||||
}
|
||||
if (selectedMonthIndex == 0) {
|
||||
monthView.setItems(months);
|
||||
} else {
|
||||
monthView.setItems(months, selectedMonthIndex);
|
||||
}
|
||||
monthView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedMonthIndex = selectedIndex;
|
||||
if (mode != YEAR_MONTH) {
|
||||
//年月日或年月模式下,需要根据年份及月份动态计算天数
|
||||
days.clear();
|
||||
int maxDays = DateUtils.calculateDaysInMonth(stringToYearMonthDay(years.get(selectedYearIndex)), stringToYearMonthDay(item));
|
||||
for (int i = 1; i <= maxDays; i++) {
|
||||
days.add(DateUtils.fillZero(i));
|
||||
}
|
||||
if (selectedDayIndex >= maxDays) {
|
||||
//年或月变动时,保持之前选择的日不动:如果之前选择的日是之前年月的最大日,则日自动为该年月的最大日
|
||||
selectedDayIndex = days.size() - 1;
|
||||
}
|
||||
dayView.setItems(days, selectedDayIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (mode != YEAR_MONTH) {
|
||||
if (!TextUtils.isEmpty(dayLabel)) {
|
||||
dayTextView.setText(dayLabel);
|
||||
}
|
||||
if (selectedDayIndex == 0) {
|
||||
dayView.setItems(days);
|
||||
} else {
|
||||
dayView.setItems(days, selectedDayIndex);
|
||||
}
|
||||
dayView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedDayIndex = selectedIndex;
|
||||
}
|
||||
});
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
private int stringToYearMonthDay(String text) {
|
||||
if (text.startsWith("0")) {
|
||||
//截取掉前缀0以便转换为整数
|
||||
text = text.substring(1);
|
||||
}
|
||||
return Integer.parseInt(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit() {
|
||||
if (onDatePickListener != null) {
|
||||
String year = getSelectedYear();
|
||||
String month = getSelectedMonth();
|
||||
String day = getSelectedDay();
|
||||
switch (mode) {
|
||||
case YEAR_MONTH:
|
||||
((OnYearMonthPickListener) onDatePickListener).onDatePicked(year, month);
|
||||
break;
|
||||
case MONTH_DAY:
|
||||
((OnMonthDayPickListener) onDatePickListener).onDatePicked(month, day);
|
||||
break;
|
||||
default:
|
||||
((OnYearMonthDayPickListener) onDatePickListener).onDatePicked(year, month, day);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected year.
|
||||
*
|
||||
* @return the selected year
|
||||
*/
|
||||
public String getSelectedYear() {
|
||||
return years.get(selectedYearIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected month.
|
||||
*
|
||||
* @return the selected month
|
||||
*/
|
||||
public String getSelectedMonth() {
|
||||
return months.get(selectedMonthIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected day.
|
||||
*
|
||||
* @return the selected day
|
||||
*/
|
||||
public String getSelectedDay() {
|
||||
return days.get(selectedDayIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On date pick listener.
|
||||
*/
|
||||
protected interface OnDatePickListener {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On year month day pick listener.
|
||||
*/
|
||||
public interface OnYearMonthDayPickListener extends OnDatePickListener {
|
||||
|
||||
/**
|
||||
* On date picked.
|
||||
*
|
||||
* @param year the year
|
||||
* @param month the month
|
||||
* @param day the day
|
||||
*/
|
||||
void onDatePicked(String year, String month, String day);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On year month pick listener.
|
||||
*/
|
||||
public interface OnYearMonthPickListener extends OnDatePickListener {
|
||||
|
||||
/**
|
||||
* On date picked.
|
||||
*
|
||||
* @param year the year
|
||||
* @param month the month
|
||||
*/
|
||||
void onDatePicked(String year, String month);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On month day pick listener.
|
||||
*/
|
||||
public interface OnMonthDayPickListener extends OnDatePickListener {
|
||||
|
||||
/**
|
||||
* On date picked.
|
||||
*
|
||||
* @param month the month
|
||||
* @param day the day
|
||||
*/
|
||||
void onDatePicked(String month, String day);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import cn.qqtheme.framework.util.LogUtils;
|
||||
import cn.qqtheme.framework.widget.WheelView;
|
||||
|
||||
/**
|
||||
* 地址选择器(包括省级、地级、县级)。
|
||||
* 地址数据见示例项目的“city.json”,来源于国家统计局官网(http://www.stats.gov.cn/tjsj/tjbz/xzqhdm)
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/15
|
||||
*/
|
||||
public class MyTimePicker extends WheelPicker {
|
||||
private ArrayList<String> provinceList = new ArrayList<String>();
|
||||
private ArrayList<String> cityList = new ArrayList<String>();
|
||||
private ArrayList<String> countyList = new ArrayList<String>();
|
||||
private OnAddressPickListener onAddressPickListener;
|
||||
private String selectedProvince = "", selectedCity = "", selectedCounty = "";
|
||||
private int selectedProvinceIndex = 0, selectedCityIndex = 0, selectedCountyIndex = 0;
|
||||
private boolean hideProvince = false;
|
||||
private boolean hideCounty = false;
|
||||
//
|
||||
// /**
|
||||
// * Instantiates a new Address picker.
|
||||
// *
|
||||
// * @param activity the activity
|
||||
// * @param data the data
|
||||
// */
|
||||
// public MyTimePicker(Activity activity, ArrayList<String> provinceList,ArrayList<String> cityList ,ArrayList<String> countyList) {
|
||||
// super(activity);
|
||||
//
|
||||
//// int provinceSize = data.size();
|
||||
//// //添加省
|
||||
//// for (int x = 0; x < provinceSize; x++) {
|
||||
//// Province pro = data.get(x);
|
||||
//// provinceList.add(pro.getAreaName());
|
||||
//// ArrayList<City> cities = pro.getCities();
|
||||
//// ArrayList<String> xCities = new ArrayList<String>();
|
||||
//// ArrayList<ArrayList<String>> xCounties = new ArrayList<ArrayList<String>>();
|
||||
//// int citySize = cities.size();
|
||||
//// //添加地市
|
||||
//// for (int y = 0; y < citySize; y++) {
|
||||
//// City cit = cities.get(y);
|
||||
//// xCities.add(cit.getAreaName());
|
||||
//// ArrayList<County> counties = cit.getCounties();
|
||||
//// ArrayList<String> yCounties = new ArrayList<String>();
|
||||
//// int countySize = counties.size();
|
||||
//// //添加区县
|
||||
//// if (countySize == 0) {
|
||||
//// yCounties.add(cit.getAreaName());
|
||||
//// } else {
|
||||
//// for (int z = 0; z < countySize; z++) {
|
||||
//// yCounties.add(counties.get(z).getAreaName());
|
||||
//// }
|
||||
//// }
|
||||
//// xCounties.add(yCounties);
|
||||
//// }
|
||||
//// cityList.add(xCities);
|
||||
//// countyList.add(xCounties);
|
||||
//// }
|
||||
// }
|
||||
|
||||
public MyTimePicker(Activity activity, ArrayList<String> provinceList, ArrayList<String> cityList, ArrayList<String> countyList) {
|
||||
super(activity);
|
||||
this.provinceList = provinceList;
|
||||
this.cityList = cityList;
|
||||
this.countyList = countyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param selectedProvinceIndex the province
|
||||
* @param selectedCityIndex the city
|
||||
* @param selectedCountyIndex the county
|
||||
*/
|
||||
public void setSelectedItem(int selectedProvinceIndex, int selectedCityIndex,int selectedCountyIndex) {
|
||||
this.selectedProvinceIndex=selectedProvinceIndex;
|
||||
this.selectedCityIndex=selectedCityIndex;
|
||||
this.selectedCountyIndex=selectedCountyIndex;
|
||||
// LogUtils.debug(String.format("init select index: %s-%s-%s", selectedProvinceIndex, selectedCityIndex, selectedCountyIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏省级行政区,只显示地市级和区县级。
|
||||
* 设置为true的话,地址数据中只需要某个省份的即可
|
||||
* 参见示例中的“city2.json”
|
||||
*
|
||||
* @param hideProvince the hide province
|
||||
*/
|
||||
public void setHideProvince(boolean hideProvince) {
|
||||
this.hideProvince = hideProvince;
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏县级行政区,只显示省级和市级。
|
||||
* 设置为true的话,hideProvince将强制为false
|
||||
* 数据源依然使用“city.json” 仅在逻辑上隐藏县级选择框。
|
||||
*
|
||||
* @param hideCounty the hide county
|
||||
*/
|
||||
public void setHideCounty(boolean hideCounty) {
|
||||
this.hideCounty = hideCounty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on address pick listener.
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void setOnAddressPickListener(OnAddressPickListener listener) {
|
||||
this.onAddressPickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected View makeCenterView() {
|
||||
if (hideCounty) {
|
||||
hideProvince = false;
|
||||
}
|
||||
if (provinceList.size() == 0) {
|
||||
throw new IllegalArgumentException("please initial options at first, can't be empty");
|
||||
}
|
||||
LinearLayout layout = new LinearLayout(activity);
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setGravity(Gravity.CENTER);
|
||||
final WheelView provinceView = new WheelView(activity);
|
||||
provinceView.setLayoutParams(new LinearLayout.LayoutParams(screenWidthPixels / 3, WRAP_CONTENT));
|
||||
provinceView.setTextSize(textSize);
|
||||
provinceView.setTextColor(textColorNormal, textColorFocus);
|
||||
provinceView.setLineVisible(lineVisible);
|
||||
provinceView.setLineColor(lineColor);
|
||||
provinceView.setOffset(offset);
|
||||
layout.addView(provinceView);
|
||||
if (hideProvince) {
|
||||
provinceView.setVisibility(View.GONE);
|
||||
}
|
||||
final WheelView cityView = new WheelView(activity);
|
||||
cityView.setLayoutParams(new LinearLayout.LayoutParams(screenWidthPixels / 3, WRAP_CONTENT));
|
||||
cityView.setTextSize(textSize);
|
||||
cityView.setTextColor(textColorNormal, textColorFocus);
|
||||
cityView.setLineVisible(lineVisible);
|
||||
cityView.setLineColor(lineColor);
|
||||
cityView.setOffset(offset);
|
||||
layout.addView(cityView);
|
||||
final WheelView countyView = new WheelView(activity);
|
||||
countyView.setLayoutParams(new LinearLayout.LayoutParams(screenWidthPixels / 3, WRAP_CONTENT));
|
||||
countyView.setTextSize(textSize);
|
||||
countyView.setTextColor(textColorNormal, textColorFocus);
|
||||
countyView.setLineVisible(lineVisible);
|
||||
countyView.setLineColor(lineColor);
|
||||
countyView.setOffset(offset);
|
||||
layout.addView(countyView);
|
||||
if (hideCounty) {
|
||||
countyView.setVisibility(View.GONE);
|
||||
}
|
||||
provinceView.setItems(provinceList, selectedProvinceIndex);
|
||||
provinceView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedProvince = item;
|
||||
selectedProvinceIndex = selectedIndex;
|
||||
if(0==selectedIndex){
|
||||
cityView.setItems(cityList.subList(getSelectHours(),cityList.size()),0);
|
||||
countyView.setItems(countyList.subList(getSelectMinutes(),countyList.size()),0);
|
||||
}else{
|
||||
cityView.setItems(cityList,selectedCityIndex);
|
||||
countyView.setItems(countyList, selectedCountyIndex);
|
||||
}
|
||||
//根据省份获取地市
|
||||
// cityView.setItems(cityList, isUserScroll ? 0 : selectedCityIndex);
|
||||
// //根据地市获取区县
|
||||
// countyView.setItems(countyList, isUserScroll ? 0 : selectedCountyIndex);
|
||||
}
|
||||
});
|
||||
// cityView.setItems(cityList,selectedCityIndex);
|
||||
cityView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedCity = item;
|
||||
selectedCityIndex = selectedIndex;
|
||||
//根据地市获取区县
|
||||
// countyView.setItems(countyList, isUserScroll ? 0 : selectedCountyIndex);
|
||||
}
|
||||
});
|
||||
// countyView.setItems(countyList, selectedCountyIndex);
|
||||
countyView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedCounty = item;
|
||||
selectedCountyIndex = selectedIndex;
|
||||
System.out.println("selectedCountyIndex="+selectedCountyIndex);
|
||||
}
|
||||
});
|
||||
return layout;
|
||||
}
|
||||
private int getSelectHours() {
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH时");
|
||||
|
||||
Calendar c = Calendar.getInstance();
|
||||
Date monday = c.getTime();
|
||||
String preMonday = sdf.format(monday);
|
||||
return cityList.indexOf(preMonday);
|
||||
}
|
||||
private int getSelectMinutes() {
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("mm分");
|
||||
|
||||
Calendar c = Calendar.getInstance();
|
||||
Date monday = c.getTime();
|
||||
String preMonday = sdf.format(monday);
|
||||
return countyList.indexOf(preMonday);
|
||||
}
|
||||
@Override
|
||||
public void onSubmit() {
|
||||
if (onAddressPickListener != null) {
|
||||
if (hideCounty) {
|
||||
onAddressPickListener.onAddressPicked(selectedProvince, selectedCity, null);
|
||||
} else {
|
||||
onAddressPickListener.onAddressPicked(selectedProvince, selectedCity, selectedCounty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On address pick listener.
|
||||
*/
|
||||
public interface OnAddressPickListener {
|
||||
|
||||
/**
|
||||
* On address picked.
|
||||
*
|
||||
* @param province the province
|
||||
* @param city the city
|
||||
* @param county the county ,if {@hideCounty} is true,this is null
|
||||
*/
|
||||
void onAddressPicked(String province, String city, String county);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Area.
|
||||
*/
|
||||
public abstract static class Area {
|
||||
/**
|
||||
* The Area id.
|
||||
*/
|
||||
String areaId;
|
||||
/**
|
||||
* The Area name.
|
||||
*/
|
||||
String areaName;
|
||||
|
||||
/**
|
||||
* Gets area id.
|
||||
*
|
||||
* @return the area id
|
||||
*/
|
||||
public String getAreaId() {
|
||||
return areaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets area id.
|
||||
*
|
||||
* @param areaId the area id
|
||||
*/
|
||||
public void setAreaId(String areaId) {
|
||||
this.areaId = areaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets area name.
|
||||
*
|
||||
* @return the area name
|
||||
*/
|
||||
public String getAreaName() {
|
||||
return areaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets area name.
|
||||
*
|
||||
* @param areaName the area name
|
||||
*/
|
||||
public void setAreaName(String areaName) {
|
||||
this.areaName = areaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "areaId=" + areaId + ",areaName=" + areaName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Province.
|
||||
*/
|
||||
public static class Province extends Area {
|
||||
/**
|
||||
* The Cities.
|
||||
*/
|
||||
ArrayList<City> cities = new ArrayList<City>();
|
||||
|
||||
/**
|
||||
* Gets cities.
|
||||
*
|
||||
* @return the cities
|
||||
*/
|
||||
public ArrayList<City> getCities() {
|
||||
return cities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cities.
|
||||
*
|
||||
* @param cities the cities
|
||||
*/
|
||||
public void setCities(ArrayList<City> cities) {
|
||||
this.cities = cities;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type City.
|
||||
*/
|
||||
public static class City extends Area {
|
||||
private ArrayList<County> counties = new ArrayList<County>();
|
||||
|
||||
/**
|
||||
* Gets counties.
|
||||
*
|
||||
* @return the counties
|
||||
*/
|
||||
public ArrayList<County> getCounties() {
|
||||
return counties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets counties.
|
||||
*
|
||||
* @param counties the counties
|
||||
*/
|
||||
public void setCounties(ArrayList<County> counties) {
|
||||
this.counties = counties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The type County.
|
||||
*/
|
||||
public static class County extends Area {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
/**
|
||||
* 数字选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /10/24
|
||||
*/
|
||||
public class NumberPicker extends OptionPicker {
|
||||
|
||||
/**
|
||||
* Instantiates a new Number picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public NumberPicker(Activity activity) {
|
||||
super(activity, new String[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets range.
|
||||
*
|
||||
* @param startNumber the start number
|
||||
* @param endNumber the end number
|
||||
*/
|
||||
public void setRange(int startNumber, int endNumber) {
|
||||
setRange(startNumber, endNumber, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets range.
|
||||
*
|
||||
* @param startNumber the start number
|
||||
* @param endNumber the end number
|
||||
* @param step the step
|
||||
*/
|
||||
public void setRange(int startNumber, int endNumber, int step) {
|
||||
for (int i = startNumber; i <= endNumber; i = i + step) {
|
||||
options.add(String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param number the number
|
||||
*/
|
||||
public void setSelectedItem(int number) {
|
||||
setSelectedItem(String.valueOf(number));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import cn.qqtheme.framework.widget.WheelView;
|
||||
|
||||
/**
|
||||
* 单项选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /9/29
|
||||
*/
|
||||
public class OptionPicker extends WheelPicker {
|
||||
/**
|
||||
* The Options.
|
||||
*/
|
||||
protected ArrayList<String> options = new ArrayList<String>();
|
||||
private OnOptionPickListener onOptionPickListener;
|
||||
private String selectedOption = "";
|
||||
private String label = "";
|
||||
|
||||
/**
|
||||
* Instantiates a new Option picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
* @param options the options
|
||||
*/
|
||||
public OptionPicker(Activity activity, String[] options) {
|
||||
super(activity);
|
||||
this.options.addAll(Arrays.asList(options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets label.
|
||||
*
|
||||
* @param label the label
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected index.
|
||||
*
|
||||
* @param index the index
|
||||
*/
|
||||
public void setSelectedIndex(int index) {
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
if (index == i) {
|
||||
selectedOption = options.get(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param option the option
|
||||
*/
|
||||
public void setSelectedItem(String option) {
|
||||
selectedOption = option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on option pick listener.
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void setOnOptionPickListener(OnOptionPickListener listener) {
|
||||
this.onOptionPickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected View makeCenterView() {
|
||||
if (options.size() == 0) {
|
||||
throw new IllegalArgumentException("please initial options at first, can't be empty");
|
||||
}
|
||||
LinearLayout layout = new LinearLayout(activity);
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setGravity(Gravity.CENTER);
|
||||
WheelView optionView = new WheelView(activity);
|
||||
optionView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
optionView.setTextSize(textSize);
|
||||
optionView.setTextColor(textColorNormal, textColorFocus);
|
||||
optionView.setLineVisible(lineVisible);
|
||||
optionView.setLineColor(lineColor);
|
||||
optionView.setOffset(offset);
|
||||
layout.addView(optionView);
|
||||
TextView labelView = new TextView(activity);
|
||||
labelView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
labelView.setTextColor(textColorFocus);
|
||||
labelView.setTextSize(textSize);
|
||||
layout.addView(labelView);
|
||||
if (!TextUtils.isEmpty(label)) {
|
||||
labelView.setText(label);
|
||||
}
|
||||
if (TextUtils.isEmpty(selectedOption)) {
|
||||
optionView.setItems(options);
|
||||
} else {
|
||||
optionView.setItems(options, selectedOption);
|
||||
}
|
||||
optionView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedOption = item;
|
||||
}
|
||||
});
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubmit() {
|
||||
if (onOptionPickListener != null) {
|
||||
onOptionPickListener.onOptionPicked(selectedOption);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected option.
|
||||
*
|
||||
* @return the selected option
|
||||
*/
|
||||
public String getSelectedOption() {
|
||||
return selectedOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On option pick listener.
|
||||
*/
|
||||
public interface OnOptionPickListener {
|
||||
|
||||
/**
|
||||
* On option picked.
|
||||
*
|
||||
* @param option the option
|
||||
*/
|
||||
void onOptionPicked(String option);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/15
|
||||
*/
|
||||
public class SexPicker extends OptionPicker {
|
||||
|
||||
/**
|
||||
* Instantiates a new Sex picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public SexPicker(Activity activity) {
|
||||
super(activity, new String[]{
|
||||
"男",
|
||||
"女",
|
||||
"保密"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅仅提供男和女来选择
|
||||
*/
|
||||
public void onlyMaleAndFemale() {
|
||||
options.remove(options.size() - 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
import cn.qqtheme.framework.util.DateUtils;
|
||||
import cn.qqtheme.framework.widget.WheelView;
|
||||
|
||||
/**
|
||||
* 时间选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/14
|
||||
*/
|
||||
public class TimePicker extends WheelPicker {
|
||||
/**
|
||||
* 24小时
|
||||
*/
|
||||
public static final int HOUR_OF_DAY = 0;
|
||||
/**
|
||||
* 12小时
|
||||
*/
|
||||
public static final int HOUR = 1;
|
||||
private OnTimePickListener onTimePickListener;
|
||||
private int mode;
|
||||
private String hourLabel = "时", minuteLabel = "分";
|
||||
private String selectedHour = "", selectedMinute = "";
|
||||
|
||||
/**
|
||||
* 安卓开发应避免使用枚举类(enum),因为相比于静态常量enum会花费两倍以上的内存。
|
||||
*
|
||||
* @link http ://developer.android.com/training/articles/memory.html#Overhead
|
||||
*/
|
||||
@IntDef(flag = false, value = {HOUR_OF_DAY, HOUR})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Mode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Time picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public TimePicker(Activity activity) {
|
||||
this(activity, HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Time picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
* @param mode the mode
|
||||
* @see #HOUR_OF_DAY #HOUR_OF_DAY#HOUR_OF_DAY
|
||||
* @see #HOUR #HOUR#HOUR
|
||||
*/
|
||||
public TimePicker(Activity activity, @Mode int mode) {
|
||||
super(activity);
|
||||
this.mode = mode;
|
||||
selectedHour = DateUtils.fillZero(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
|
||||
selectedMinute = DateUtils.fillZero(Calendar.getInstance().get(Calendar.MINUTE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets label.
|
||||
*
|
||||
* @param hourLabel the hour label
|
||||
* @param minuteLabel the minute label
|
||||
*/
|
||||
public void setLabel(String hourLabel, String minuteLabel) {
|
||||
this.hourLabel = hourLabel;
|
||||
this.minuteLabel = minuteLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param hour the hour
|
||||
* @param minute the minute
|
||||
*/
|
||||
public void setSelectedItem(int hour, int minute) {
|
||||
selectedHour = String.valueOf(hour);
|
||||
selectedMinute = String.valueOf(minute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on time pick listener.
|
||||
*
|
||||
* @param listener the listener
|
||||
*/
|
||||
public void setOnTimePickListener(OnTimePickListener listener) {
|
||||
this.onTimePickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected View makeCenterView() {
|
||||
LinearLayout layout = new LinearLayout(activity);
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setGravity(Gravity.CENTER);
|
||||
WheelView hourView = new WheelView(activity);
|
||||
hourView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
hourView.setTextSize(textSize);
|
||||
hourView.setTextColor(textColorNormal, textColorFocus);
|
||||
hourView.setLineVisible(lineVisible);
|
||||
hourView.setLineColor(lineColor);
|
||||
layout.addView(hourView);
|
||||
TextView hourTextView = new TextView(activity);
|
||||
hourTextView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
hourTextView.setTextSize(textSize);
|
||||
hourTextView.setTextColor(textColorFocus);
|
||||
if (!TextUtils.isEmpty(hourLabel)) {
|
||||
hourTextView.setText(hourLabel);
|
||||
}
|
||||
layout.addView(hourTextView);
|
||||
WheelView minuteView = new WheelView(activity);
|
||||
minuteView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
minuteView.setTextSize(textSize);
|
||||
minuteView.setTextColor(textColorNormal, textColorFocus);
|
||||
minuteView.setLineVisible(lineVisible);
|
||||
minuteView.setLineColor(lineColor);
|
||||
minuteView.setOffset(offset);
|
||||
layout.addView(minuteView);
|
||||
TextView minuteTextView = new TextView(activity);
|
||||
minuteTextView.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
minuteTextView.setTextSize(textSize);
|
||||
minuteTextView.setTextColor(textColorFocus);
|
||||
if (!TextUtils.isEmpty(minuteLabel)) {
|
||||
minuteTextView.setText(minuteLabel);
|
||||
}
|
||||
layout.addView(minuteTextView);
|
||||
ArrayList<String> hours = new ArrayList<String>();
|
||||
if (mode == HOUR) {
|
||||
for (int i = 1; i <= 12; i++) {
|
||||
hours.add(DateUtils.fillZero(i));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 24; i++) {
|
||||
hours.add(DateUtils.fillZero(i));
|
||||
}
|
||||
}
|
||||
hourView.setItems(hours, selectedHour);
|
||||
ArrayList<String> minutes = new ArrayList<String>();
|
||||
for (int i = 0; i < 60; i++) {
|
||||
minutes.add(DateUtils.fillZero(i));
|
||||
}
|
||||
minuteView.setItems(minutes, selectedMinute);
|
||||
hourView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedHour = item;
|
||||
}
|
||||
});
|
||||
minuteView.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
|
||||
@Override
|
||||
public void onSelected(boolean isUserScroll, int selectedIndex, String item) {
|
||||
selectedMinute = item;
|
||||
}
|
||||
});
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubmit() {
|
||||
if (onTimePickListener != null) {
|
||||
onTimePickListener.onTimePicked(selectedHour, selectedMinute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected hour.
|
||||
*
|
||||
* @return the selected hour
|
||||
*/
|
||||
public String getSelectedHour() {
|
||||
return selectedHour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected minute.
|
||||
*
|
||||
* @return the selected minute
|
||||
*/
|
||||
public String getSelectedMinute() {
|
||||
return selectedMinute;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On time pick listener.
|
||||
*/
|
||||
public interface OnTimePickListener {
|
||||
|
||||
/**
|
||||
* On time picked.
|
||||
*
|
||||
* @param hour the hour
|
||||
* @param minute the minute
|
||||
*/
|
||||
void onTimePicked(String hour, String minute);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.IntRange;
|
||||
import android.view.View;
|
||||
|
||||
import cn.qqtheme.framework.popup.ConfirmPopup;
|
||||
import cn.qqtheme.framework.widget.WheelView;
|
||||
|
||||
/**
|
||||
* 滑轮选择器
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /12/22
|
||||
*/
|
||||
public abstract class WheelPicker extends ConfirmPopup<View> {
|
||||
/**
|
||||
* The Text size.
|
||||
*/
|
||||
protected int textSize = WheelView.TEXT_SIZE;
|
||||
/**
|
||||
* The Text color normal.
|
||||
*/
|
||||
protected int textColorNormal = WheelView.TEXT_COLOR_NORMAL;
|
||||
/**
|
||||
* The Text color focus.
|
||||
*/
|
||||
protected int textColorFocus = WheelView.TEXT_COLOR_FOCUS;
|
||||
/**
|
||||
* The Line color.
|
||||
*/
|
||||
protected int lineColor = WheelView.LINE_COLOR;
|
||||
/**
|
||||
* The Line visible.
|
||||
*/
|
||||
protected boolean lineVisible = true;
|
||||
/**
|
||||
* The Offset.
|
||||
*/
|
||||
protected int offset = WheelView.OFF_SET;
|
||||
|
||||
/**
|
||||
* Instantiates a new Wheel picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public WheelPicker(Activity activity) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text size.
|
||||
*
|
||||
* @param textSize the text size
|
||||
*/
|
||||
public void setTextSize(int textSize) {
|
||||
this.textSize = textSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text color.
|
||||
*
|
||||
* @param textColorFocus the text color focus
|
||||
* @param textColorNormal the text color normal
|
||||
*/
|
||||
public void setTextColor(@ColorInt int textColorFocus, @ColorInt int textColorNormal) {
|
||||
this.textColorFocus = textColorFocus;
|
||||
this.textColorNormal = textColorNormal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text color.
|
||||
*
|
||||
* @param textColor the text color
|
||||
*/
|
||||
public void setTextColor(@ColorInt int textColor) {
|
||||
this.textColorFocus = textColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets line visible.
|
||||
*
|
||||
* @param lineVisible the line visible
|
||||
*/
|
||||
public void setLineVisible(boolean lineVisible) {
|
||||
this.lineVisible = lineVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets line color.
|
||||
*
|
||||
* @param lineColor the line color
|
||||
*/
|
||||
public void setLineColor(@ColorInt int lineColor) {
|
||||
this.lineColor = lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets offset.
|
||||
*
|
||||
* @param offset the offset
|
||||
*/
|
||||
public void setOffset(@IntRange(from = 1, to = 4) int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,617 @@
|
||||
package cn.qqtheme.framework.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.qqtheme.framework.util.LogUtils;
|
||||
|
||||
/**
|
||||
* 基于原版作了一下修改:
|
||||
* 去掉回弹阴影
|
||||
* 修正以便支持联动效果
|
||||
* 可设置颜色
|
||||
* 设置文字大小
|
||||
* 分隔线是否可见
|
||||
* 初始设置选中选项
|
||||
*
|
||||
* @author 李玉江[QQ :1023694760]
|
||||
* @version 2015 -12-17
|
||||
* @link https ://github.com/wangjiegulu/WheelView
|
||||
*/
|
||||
public class WheelView extends ScrollView {
|
||||
/**
|
||||
* The constant TEXT_SIZE.
|
||||
*/
|
||||
public static final int TEXT_SIZE = 20;
|
||||
/**
|
||||
* The constant TEXT_COLOR_FOCUS.
|
||||
*/
|
||||
public static final int TEXT_COLOR_FOCUS = 0XFF0288CE;
|
||||
/**
|
||||
* The constant TEXT_COLOR_NORMAL.
|
||||
*/
|
||||
public static final int TEXT_COLOR_NORMAL = 0XFFBBBBBB;
|
||||
/**
|
||||
* The constant LINE_COLOR.
|
||||
*/
|
||||
public static final int LINE_COLOR = 0XFF83CDE6;
|
||||
/**
|
||||
* The constant OFF_SET.
|
||||
*/
|
||||
public static final int OFF_SET = 1;
|
||||
private static final int DELAY = 50;
|
||||
|
||||
private Context context;
|
||||
private LinearLayout views;
|
||||
private List<String> items = new ArrayList<String>();
|
||||
private int offset = OFF_SET; // 偏移量(需要在最前面和最后面补全)
|
||||
|
||||
private int displayItemCount; // 每页显示的数量
|
||||
|
||||
private int selectedIndex = OFF_SET;
|
||||
private int initialY;
|
||||
|
||||
private Runnable scrollerTask = new ScrollerTask();
|
||||
private int itemHeight = 0;
|
||||
private int[] selectedAreaBorder;//获取选中区域的边界
|
||||
private OnWheelViewListener onWheelViewListener;
|
||||
|
||||
private Paint paint;
|
||||
private int viewWidth;
|
||||
private int textSize = TEXT_SIZE;
|
||||
private int textColorNormal = TEXT_COLOR_NORMAL;
|
||||
private int textColorFocus = TEXT_COLOR_FOCUS;
|
||||
private int lineColor = LINE_COLOR;
|
||||
private boolean lineVisible = true;
|
||||
private boolean isUserScroll = false;//是否用户手动滚动
|
||||
private float previousY = 0;//记录按下时的Y坐标
|
||||
|
||||
/**
|
||||
* Instantiates a new Wheel view.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public WheelView(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Wheel view.
|
||||
*
|
||||
* @param context the context
|
||||
* @param attrs the attrs
|
||||
*/
|
||||
public WheelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Wheel view.
|
||||
*
|
||||
* @param context the context
|
||||
* @param attrs the attrs
|
||||
* @param defStyle the def style
|
||||
*/
|
||||
public WheelView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
this.context = context;
|
||||
|
||||
// 2015/12/15 去掉ScrollView的阴影
|
||||
setFadingEdgeLength(0);
|
||||
if (Build.VERSION.SDK_INT >= 9) {
|
||||
setOverScrollMode(OVER_SCROLL_NEVER);
|
||||
}
|
||||
|
||||
setVerticalScrollBarEnabled(false);
|
||||
|
||||
views = new LinearLayout(context);
|
||||
views.setOrientation(LinearLayout.VERTICAL);
|
||||
addView(views);
|
||||
}
|
||||
|
||||
private void startScrollerTask() {
|
||||
initialY = getScrollY();
|
||||
postDelayed(scrollerTask, DELAY);
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
displayItemCount = offset * 2 + 1;
|
||||
|
||||
// 2015/12/15 添加此句才可以支持联动效果
|
||||
views.removeAllViews();
|
||||
|
||||
for (String item : items) {
|
||||
views.addView(createView(item));
|
||||
}
|
||||
|
||||
// 2016/1/15 焦点文字颜色高亮位置,逆推“int position = y / itemHeight + offset”
|
||||
refreshItemView(itemHeight * (selectedIndex - offset));
|
||||
}
|
||||
|
||||
private TextView createView(String item) {
|
||||
TextView tv = new TextView(context);
|
||||
tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
tv.setSingleLine(true);
|
||||
tv.setEllipsize(TextUtils.TruncateAt.END);
|
||||
tv.setText(item);
|
||||
tv.setTextSize(textSize);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
int padding = dip2px(15);
|
||||
tv.setPadding(padding, padding, padding, padding);
|
||||
if (0 == itemHeight) {
|
||||
itemHeight = getViewMeasuredHeight(tv);
|
||||
LogUtils.debug(this, "itemHeight: " + itemHeight);
|
||||
views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight * displayItemCount));
|
||||
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
|
||||
setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight * displayItemCount));
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
|
||||
|
||||
private void refreshItemView(int y) {
|
||||
int position = y / itemHeight + offset;
|
||||
int remainder = y % itemHeight;
|
||||
int divided = y / itemHeight;
|
||||
|
||||
if (remainder == 0) {
|
||||
position = divided + offset;
|
||||
} else {
|
||||
if (remainder > itemHeight / 2) {
|
||||
position = divided + offset + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int childSize = views.getChildCount();
|
||||
for (int i = 0; i < childSize; i++) {
|
||||
TextView itemView = (TextView) views.getChildAt(i);
|
||||
if (null == itemView) {
|
||||
return;
|
||||
}
|
||||
// 2015/12/15 可设置颜色
|
||||
if (position == i) {
|
||||
itemView.setTextColor(textColorFocus);
|
||||
} else {
|
||||
itemView.setTextColor(textColorNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int[] obtainSelectedAreaBorder() {
|
||||
if (null == selectedAreaBorder) {
|
||||
selectedAreaBorder = new int[2];
|
||||
selectedAreaBorder[0] = itemHeight * offset;
|
||||
selectedAreaBorder[1] = itemHeight * (offset + 1);
|
||||
}
|
||||
return selectedAreaBorder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中回调
|
||||
*/
|
||||
private void onSelectedCallBack() {
|
||||
if (null != onWheelViewListener) {
|
||||
// 2015/12/25 真实的index应该忽略偏移量
|
||||
onWheelViewListener.onSelected(isUserScroll, selectedIndex - offset, items.get(selectedIndex));
|
||||
}
|
||||
}
|
||||
|
||||
private int dip2px(float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
private int getViewMeasuredHeight(View view) {
|
||||
int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
|
||||
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
|
||||
view.measure(width, expandSpec);
|
||||
return view.getMeasuredHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Drawable background) {
|
||||
setBackgroundDrawable(background);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setBackgroundDrawable(Drawable background) {
|
||||
if (viewWidth == 0) {
|
||||
viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
|
||||
LogUtils.debug(this, "viewWidth: " + viewWidth);
|
||||
}
|
||||
|
||||
// 2015/12/22 可设置分隔线是否可见
|
||||
if (!lineVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null == paint) {
|
||||
paint = new Paint();
|
||||
paint.setColor(lineColor);
|
||||
paint.setStrokeWidth(dip2px(1f));
|
||||
}
|
||||
|
||||
background = new Drawable() {
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
int[] areaBorder = obtainSelectedAreaBorder();
|
||||
canvas.drawLine(0, areaBorder[0], viewWidth , areaBorder[0], paint);
|
||||
canvas.drawLine(0, areaBorder[1], viewWidth , areaBorder[1], paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
super.setBackgroundDrawable(background);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||
super.onScrollChanged(l, t, oldl, oldt);
|
||||
refreshItemView(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
LogUtils.debug(this, "w: " + w + ", h: " + h + ", oldw: " + oldw + ", oldh: " + oldh);
|
||||
viewWidth = w;
|
||||
setBackgroundDrawable(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fling(int velocityY) {
|
||||
super.fling(velocityY / 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
previousY = ev.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
LogUtils.debug(this, String.format("items=%s, offset=%s", items.size(), offset));
|
||||
LogUtils.debug(this, "selectedIndex=" + selectedIndex);
|
||||
float delta = ev.getY() - previousY;
|
||||
LogUtils.debug(this, "delta=" + delta);
|
||||
if (selectedIndex == offset && delta > 0) {
|
||||
//滑动到第一项时,若继续向下滑动,则自动跳到最后一项
|
||||
setSelectedIndex(items.size() - offset * 2 - 1);
|
||||
} else if (selectedIndex == items.size() - offset - 1 && delta < 0) {
|
||||
//滑动到最后一项时,若继续向上滑动,则自动跳到第一项
|
||||
setSelectedIndex(0);
|
||||
} else {
|
||||
isUserScroll = true;
|
||||
startScrollerTask();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
private void _setItems(List<String> list) {
|
||||
items.clear();
|
||||
items.addAll(list);
|
||||
|
||||
// 前面和后面补全
|
||||
for (int i = 0; i < offset; i++) {
|
||||
items.add(0, "");
|
||||
items.add("");
|
||||
}
|
||||
|
||||
initData();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets items.
|
||||
*
|
||||
* @param list the list
|
||||
*/
|
||||
public void setItems(List<String> list) {
|
||||
_setItems(list);
|
||||
// 2015/12/25 初始化时设置默认选中项
|
||||
setSelectedIndex(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets items.
|
||||
*
|
||||
* @param list the list
|
||||
* @param index the index
|
||||
*/
|
||||
public void setItems(List<String> list, int index) {
|
||||
_setItems(list);
|
||||
setSelectedIndex(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets items.
|
||||
*
|
||||
* @param list the list
|
||||
* @param item the item
|
||||
*/
|
||||
public void setItems(List<String> list, String item) {
|
||||
_setItems(list);
|
||||
setSelectedItem(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text size.
|
||||
*
|
||||
* @return the text size
|
||||
*/
|
||||
public int getTextSize() {
|
||||
return textSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text size.
|
||||
*
|
||||
* @param textSize the text size
|
||||
*/
|
||||
public void setTextSize(int textSize) {
|
||||
this.textSize = textSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets text color.
|
||||
*
|
||||
* @return the text color
|
||||
*/
|
||||
public int getTextColor() {
|
||||
return textColorFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text color.
|
||||
*
|
||||
* @param textColorNormal the text color normal
|
||||
* @param textColorFocus the text color focus
|
||||
*/
|
||||
public void setTextColor(@ColorInt int textColorNormal, @ColorInt int textColorFocus) {
|
||||
this.textColorNormal = textColorNormal;
|
||||
this.textColorFocus = textColorFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text color.
|
||||
*
|
||||
* @param textColor the text color
|
||||
*/
|
||||
public void setTextColor(@ColorInt int textColor) {
|
||||
this.textColorFocus = textColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is line visible boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isLineVisible() {
|
||||
return lineVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets line visible.
|
||||
*
|
||||
* @param lineVisible the line visible
|
||||
*/
|
||||
public void setLineVisible(boolean lineVisible) {
|
||||
this.lineVisible = lineVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets line color.
|
||||
*
|
||||
* @return the line color
|
||||
*/
|
||||
public int getLineColor() {
|
||||
return lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets line color.
|
||||
*
|
||||
* @param lineColor the line color
|
||||
*/
|
||||
public void setLineColor(@ColorInt int lineColor) {
|
||||
this.lineColor = lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets offset.
|
||||
*
|
||||
* @return the offset
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets offset.
|
||||
*
|
||||
* @param offset the offset
|
||||
*/
|
||||
public void setOffset(int offset) {
|
||||
if (offset < 1 || offset > 4) {
|
||||
throw new IllegalArgumentException("Offset must between 1 and 4");
|
||||
}
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从0开始计数,所有项包括偏移量
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
private void setSelectedIndex(final int index) {
|
||||
isUserScroll = false;
|
||||
this.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//滚动到选中项的位置
|
||||
smoothScrollTo(0, index * itemHeight);
|
||||
//选中这一项的值
|
||||
selectedIndex = index + offset;
|
||||
onSelectedCallBack();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selected item.
|
||||
*
|
||||
* @param item the item
|
||||
*/
|
||||
public void setSelectedItem(String item) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
if (items.get(i).equals(item)) {
|
||||
//调用_setItems(List)时额外添加了offset个占位符到items里,需要忽略占位符所占的位
|
||||
setSelectedIndex(i - offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #getSelectedItem()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public String getSeletedItem() {
|
||||
return getSelectedItem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected item.
|
||||
*
|
||||
* @return the selected item
|
||||
*/
|
||||
public String getSelectedItem() {
|
||||
return items.get(selectedIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #getSelectedIndex()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getSeletedIndex() {
|
||||
return getSelectedIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected index.
|
||||
*
|
||||
* @return the selected index
|
||||
*/
|
||||
public int getSelectedIndex() {
|
||||
return selectedIndex - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on wheel view listener.
|
||||
*
|
||||
* @param onWheelViewListener the on wheel view listener
|
||||
*/
|
||||
public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) {
|
||||
this.onWheelViewListener = onWheelViewListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On wheel view listener.
|
||||
*/
|
||||
public interface OnWheelViewListener {
|
||||
/**
|
||||
* On selected.
|
||||
*
|
||||
* @param isUserScroll the is user scroll
|
||||
* @param selectedIndex the selected index
|
||||
* @param item the item
|
||||
*/
|
||||
void onSelected(boolean isUserScroll, int selectedIndex, String item);
|
||||
}
|
||||
|
||||
private class ScrollerTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 2015/12/17 java.lang.ArithmeticException: divide by zero
|
||||
if (itemHeight == 0) {
|
||||
LogUtils.debug(this, "itemHeight is zero");
|
||||
return;
|
||||
}
|
||||
int newY = getScrollY();
|
||||
if (initialY - newY == 0) { // stopped
|
||||
final int remainder = initialY % itemHeight;
|
||||
final int divided = initialY / itemHeight;
|
||||
LogUtils.debug(this, "initialY: " + initialY + ", remainder: " + remainder + ", divided: " + divided);
|
||||
if (remainder == 0) {
|
||||
selectedIndex = divided + offset;
|
||||
onSelectedCallBack();
|
||||
} else {
|
||||
if (remainder > itemHeight / 2) {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
smoothScrollTo(0, initialY - remainder + itemHeight);
|
||||
selectedIndex = divided + offset + 1;
|
||||
onSelectedCallBack();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
smoothScrollTo(0, initialY - remainder);
|
||||
selectedIndex = divided + offset;
|
||||
onSelectedCallBack();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
startScrollerTask();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user