在開(kāi)發(fā)中如果有地址或者日期選擇等就會(huì)涉及到時(shí)間或者條件選擇器,大家都會(huì)想到仿iOS的三級(jí)聯(lián)動(dòng)的效果,用wheelview實(shí)現(xiàn),其實(shí)安卓原生自帶了時(shí)間和日期選擇器可能是效果來(lái)說(shuō)太粗獷了,所以很多產(chǎn)品效果圖都是清一色的ios那種效果,ok,廢話說(shuō)完了上圖
Demo地址:
1,安卓原生的時(shí)間和日期選擇器
代碼:download.csdn.net/download/qq_32487869/10111865
DatePickerDialog dialog = new
DatePickerDialog(MainActivity.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int
dayOfMonth) {
if(monthOfYear<=9){
mouth1="0"+(monthOfYear+1);
}else{
mouth1=String.valueOf(monthOfYear+1);
}
if(dayOfMonth<=9){
day1= "0"+dayOfMonth;
}else{
day1=String.valueOf(dayOfMonth);
}
dateStr = String.valueOf(year)+"-"+mouth1+"-"+day1;
button1.setText(dateStr);
}
}, calender.get(Calendar.YEAR), calender.get(Calendar.MONTH),
calender.get(Calendar.DAY_OF_MONTH));
dialog.show();
使用非常簡(jiǎn)單,自己寫個(gè)時(shí)間過(guò)濾方法就行
TimePickerDialog dialog = new TimePickerDialog(MainActivity.this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
button2.setText(String.valueOf(hourOfDay+":"+minute));
}
},calender2.get(Calendar.HOUR),calender2.get(Calendar.MINUTE),false);
dialog.show();
DatePickerDialog和TimePickerDialog都是原生帶的,在5.0之前還是和ios那種效果差不多,來(lái)回上下滑選擇日期的,但是5.0后就成日歷了,雖然好看,不過(guò)占比屏太大,設(shè)計(jì)并不會(huì)考慮這種效果,哎,現(xiàn)在很多安卓的控件原生其實(shí)效果不錯(cuò)的,不過(guò)還是得為了遵循產(chǎn)品和設(shè)計(jì)的意思做成仿ios效果(小小的抱怨一下)
2.開(kāi)源日期選擇器Timepickview和條件選擇器Optionspickview
代碼:timepick:
TimePickerView pvTime = new TimePickerView.Builder(MainActivity.this, new TimePickerView.OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date2, View v) {//選中事件回調(diào)
String time = getTime(date2);
button3.setText(time);
}
})
.setType(TimePickerView.Type.YEAR_MONTH_DAY)//默認(rèn)全部顯示
.setCancelText("取消")//取消按鈕文字
.setSubmitText("確定")//確認(rèn)按鈕文字
.setContentSize(20)//滾輪文字大小
.setTitleSize(20)//標(biāo)題文字大小
//? ? ? ? ? ? ? ? ? ? ? ? .setTitleText("請(qǐng)選擇時(shí)間")//標(biāo)題文字
.setOutSideCancelable(true)//點(diǎn)擊屏幕,點(diǎn)在控件外部范圍時(shí),是否取消顯示
.isCyclic(true)//是否循環(huán)滾動(dòng)
.setTextColorCenter(Color.BLACK)//設(shè)置選中項(xiàng)的顏色
.setTitleColor(Color.BLACK)//標(biāo)題文字顏色
.setSubmitColor(Color.BLUE)//確定按鈕文字顏色
.setCancelColor(Color.BLUE)//取消按鈕文字顏色
//? ? ? ? ? ? ? ? ? ? ? ? .setTitleBgColor(0xFF666666)//標(biāo)題背景顏色 Night mode
//? ? ? ? ? ? ? ? ? ? ? ? .setBgColor(0xFF333333)//滾輪背景顏色 Night mode
//? ? ? ? ? ? ? ? ? ? ? ? .setRange(calendar.get(Calendar.YEAR) - 20, calendar.get(Calendar.YEAR) + 20)//默認(rèn)是1900-2100年
//? ? ? ? ? ? ? ? ? ? ? ? .setDate(selectedDate)// 如果不設(shè)置的話,默認(rèn)是系統(tǒng)時(shí)間*/
//? ? ? ? ? ? ? ? ? ? ? ? .setRangDate(startDate,endDate)//起始終止年月日設(shè)定
//? ? ? ? ? ? ? ? ? ? ? ? .setLabel("年","月","日","時(shí)","分","秒")
.isCenterLabel(false) //是否只顯示中間選中項(xiàng)的label文字,false則每項(xiàng)item全部都帶有l(wèi)abel。
//? ? ? ? ? ? ? ? ? ? ? ? .isDialog(true)//是否顯示為對(duì)話框樣式
.build();
pvTime.setDate(Calendar.getInstance());//注:根據(jù)需求來(lái)決定是否使用該方法(一般是精確到秒的情況),此項(xiàng)可以在彈出選擇器的時(shí)候重新設(shè)置當(dāng)前時(shí)間,避免在初始化之后由于時(shí)間已經(jīng)設(shè)定,導(dǎo)致選中時(shí)間與當(dāng)前時(shí)間不匹配的問(wèn)題。
pvTime.show();
注釋已經(jīng)寫的很詳細(xì)了,各種選項(xiàng)干嘛用的
Optionspickview:代碼:
options1Items.clear();
options1Items.add("托兒索");
options1Items.add("兒童劫");
options1Items.add("小學(xué)生之手");
options1Items.add("德瑪西亞大保健");
options1Items.add("面對(duì)疾風(fēng)吧");
options1Items.add("天王蓋地虎");
options1Items.add("我發(fā)一米五");
options1Items.add("爆劉繼芬");
OptionsPickerView pvOptions = new? OptionsPickerView.Builder(MainActivity.this, new OptionsPickerView.OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
//返回的分別是三個(gè)級(jí)別的選中位置
String s =? options1Items.get(options1);
button4.setText(s);
}
})
//? ? ? ? ? ? ? ? ? ? ? ? .setSubmitText("確定")//確定按鈕文字
//? ? ? ? ? ? ? ? ? ? ? ? .setCancelText("取消")//取消按鈕文字
//? ? ? ? ? ? ? ? ? ? ? ? .setTitleText("城市選擇")//標(biāo)題
.setSubCalSize(20)//確定和取消文字大小
//? ? ? ? ? ? ? ? ? ? ? ? .setTitleSize(20)//標(biāo)題文字大小
//? ? ? ? ? ? ? ? ? ? ? ? .setTitleColor(Color.BLACK)//標(biāo)題文字顏色
.setSubmitColor(Color.BLUE)//確定按鈕文字顏色
.setCancelColor(Color.BLUE)//取消按鈕文字顏色
//? ? ? ? ? ? ? ? ? ? ? ? .setTitleBgColor(0xFF333333)//標(biāo)題背景顏色 Night mode
//? ? ? ? ? ? ? ? ? ? ? ? .setBgColor(0xFF000000)//滾輪背景顏色 Night mode
//? ? ? ? ? ? ? ? ? ? ? ? .setContentTextSize(18)//滾輪文字大小
//? ? ? ? ? ? ? ? ? ? ? ? .setTextColorCenter(Color.BLUE)//設(shè)置選中項(xiàng)的顏色
.setTextColorCenter(Color.BLACK)//設(shè)置選中項(xiàng)的顏色
//? ? ? ? ? ? ? ? ? ? ? ? .setLineSpacingMultiplier(1.6f)//設(shè)置兩橫線之間的間隔倍數(shù)
//? ? ? ? ? ? ? ? ? ? ? ? .setLinkage(false)//設(shè)置是否聯(lián)動(dòng),默認(rèn)true
//? ? ? ? ? ? ? ? ? ? ? ? .setLabels("省", "市", "區(qū)")//設(shè)置選擇的三級(jí)單位
//? ? ? ? ? ? ? ? ? ? ? ? .isCenterLabel(false) //是否只顯示中間選中項(xiàng)的label文字,false則每項(xiàng)item全部都帶有l(wèi)abel。
//? ? ? ? ? ? ? ? ? ? ? ? .setCyclic(false, false, false)//循環(huán)與否
//? ? ? ? ? ? ? ? ? ? ? ? .setSelectOptions(1, 1, 1)? //設(shè)置默認(rèn)選中項(xiàng)
//? ? ? ? ? ? ? ? ? ? ? ? .setOutSideCancelable(false)//點(diǎn)擊外部dismiss default true
//? ? ? ? ? ? ? ? ? ? ? ? .isDialog(true)//是否顯示為對(duì)話框樣式
.build();
pvOptions.setPicker(options1Items);
pvOptions.show();
條件自己定義,可以傳簡(jiǎn)單集合,也可以傳別的,比如省市縣...
轉(zhuǎn)自:www.lxweimin.com/p/ba0faf749e73
3.結(jié)合wheelview和原生timepick自定義時(shí)間選擇器
用法:
final String[] str = new String[10];
ChangeDatePopwindow mChangeBirthDialog = new ChangeDatePopwindow(MainActivity.this);
mChangeBirthDialog.setDate("2017", "6", "20");
mChangeBirthDialog.showAtLocation(main, Gravity.BOTTOM, 0, 0);
mChangeBirthDialog.setBirthdayListener(new ChangeDatePopwindow.OnBirthListener() {
@Override
public void onClick(String year, String month, String day) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,year + "-" + month + "-" + day,Toast.LENGTH_LONG).show();
StringBuilder sb = new StringBuilder();
sb.append(year.substring(0, year.length() - 1)).append("-").append(month.substring(0, day.length() - 1)).append("-").append(day);
str[0] = year + "-" + month + "-" + day;
str[1] = sb.toString();
button5.setText(str[0]);
}
});
大致思路:
年-月-日,其實(shí)是三個(gè)wheelview,然后手動(dòng)設(shè)置時(shí)間的范圍,繼承原有的adapter
一個(gè)例子
* 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;
// 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;
}
/**
* 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.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
*/
public 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
*/
public 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);
}
}
還有設(shè)置滑動(dòng)監(jiān)聽(tīng),改變?nèi)掌?/p>
wvYear.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
String currentText = (String) mYearAdapter.getItemText(wheel.getCurrentItem());
selectYear = currentText;
setTextviewSize(currentText, mYearAdapter);
currentYear = currentText.substring(0, currentText.length()-1).toString();
Log.d("currentYear==",currentYear);
setYear(currentYear);
initMonths(Integer.parseInt(month));
mMonthAdapter = new CalendarTextAdapter(context, arry_months, 0, maxTextSize, minTextSize);
wvMonth.setVisibleItems(5);
wvMonth.setViewAdapter(mMonthAdapter);
wvMonth.setCurrentItem(0);
calDays(currentYear, month);
}
});
wvYear.addScrollingListener(new OnWheelScrollListener() {
@Override
public void onScrollingStarted(WheelView wheel) {
// TODO Auto-generated method stub
}
@Override
public void onScrollingFinished(WheelView wheel) {
// TODO Auto-generated method stub
String currentText = (String) mYearAdapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mYearAdapter);
}
});
wvMonth.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
String currentText = (String) mMonthAdapter.getItemText(wheel.getCurrentItem());
selectMonth = currentText;
setTextviewSize(currentText, mMonthAdapter);
setMonth(currentText.substring(0, 1));
initDays(Integer.parseInt(day));
mDaydapter = new CalendarTextAdapter(context, arry_days, 0, maxTextSize, minTextSize);
wvDay.setVisibleItems(5);
wvDay.setViewAdapter(mDaydapter);
wvDay.setCurrentItem(0);
calDays(currentYear, month);
}
});
wvMonth.addScrollingListener(new OnWheelScrollListener() {
@Override
public void onScrollingStarted(WheelView wheel) {
// TODO Auto-generated method stub
}
@Override
public void onScrollingFinished(WheelView wheel) {
// TODO Auto-generated method stub
String currentText = (String) mMonthAdapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mMonthAdapter);
}
});
wvDay.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
String currentText = (String) mDaydapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mDaydapter);
selectDay = currentText;
}
});
wvDay.addScrollingListener(new OnWheelScrollListener() {
@Override
public void onScrollingStarted(WheelView wheel) {
// TODO Auto-generated method stub
}
@Override
public void onScrollingFinished(WheelView wheel) {
// TODO Auto-generated method stub
String currentText = (String) mDaydapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mDaydapter);
}
});
然后彈出的彈窗popuwindows里,設(shè)置時(shí)間
public String getYear() {
Calendar c = Calendar.getInstance();
return c.get(Calendar.YEAR)+"";
}
public String getMonth() {
Calendar c = Calendar.getInstance();
return c.get(Calendar.MONTH) + 1+"";
}
public String getDay() {
Calendar c = Calendar.getInstance();
return c.get(Calendar.DATE)+"";
}
public void initData() {
setDate(getYear(), getMonth(), getDay());
this.currentDay = 1+"";
this.currentMonth = 1+"";
}
/**
* 設(shè)置年月日
*
* @param year
* @param month
* @param day
*/
public void setDate(String year, String month, String day) {
selectYear = year + "年";
selectMonth = month + "月";
selectDay = day + "日";
issetdata = true;
this.currentYear = year;
this.currentMonth = month;
this.currentDay = day;
if (year == getYear()) {
this.month = getMonth();
} else {
this.month = 12+"";
}
calDays(year, month);
}
/**
* 設(shè)置年份
*
* @param year
*/
public int setYear(String year) {
int yearIndex = 0;
if (!year.equals(getYear())) {
this.month = 12+"";
} else {
this.month = getMonth();
}
for (int i = Integer.parseInt(getYear()); i > 1950; i--) {
if (i == Integer.parseInt(year)) {
return yearIndex;
}
yearIndex++;
}
return yearIndex;
}
/**
* 設(shè)置月份
*
* @param month
* @param month
* @return
*/
public int setMonth(String month) {
int monthIndex = 0;
calDays(currentYear, month);
for (int i = 1; i < Integer.parseInt(this.month); i++) {
if (Integer.parseInt(month) == i) {
return monthIndex;
} else {
monthIndex++;
}
}
return monthIndex;
}
/**
* 計(jì)算每月多少天
*
* @param month
* @param year
*/
public void calDays(String year, String month) {
boolean leayyear = false;
if (Integer.parseInt(year) % 4 == 0 && Integer.parseInt(year) % 100 != 0) {
leayyear = true;
} else {
leayyear = false;
}
for (int i = 1; i <= 12; i++) {
switch (Integer.parseInt(month)) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
this.day = 31+"";
break;
case 2:
if (leayyear) {
this.day = 29+"";
} else {
this.day = 28+"";
}
break;
case 4:
case 6:
case 9:
case 11:
this.day = 30+"";
break;
}
}
if (year.equals( getYear()) && month .equals( getMonth())) {
this.day = getDay();
}
然后設(shè)置點(diǎn)擊事件
@Override
public void onClick(View v) {
if (v == btnSure) {
if (onBirthListener != null) {
onBirthListener.onClick(selectYear, selectMonth, selectDay);
Log.d("cy",""+selectYear+""+selectMonth+""+selectDay);
}
} else if (v == btnSure) {
}? else {
dismiss();
}
dismiss();
}
其實(shí)就是點(diǎn)擊確定保存選擇的日期,取消dismiss
底下確定鍵是黃色按鈕那個(gè)就是換了個(gè)樣式而已原理都是一樣的
Demo地址:download.csdn.net/download/qq_32487869/10111865
大神勿噴,像各位大佬學(xué)習(xí)!!!