本文链接:https://blog.csdn.net/wangwo1991/article/details/85036891
在项目开发中Android基本都是在跟随ios的风格,前段时间产品经理就要求按照ios的效果,做时间、城市选择效果,真要全部自己写还真有点蛋疼,所以在网上一搜,效果不少,其中PickerView用的人还是蛮多的,所以就决定用PickerView来实现;
PickerView提供了:时间选择器和选项选择器
——TimePickerView 时间选择器,支持年月日时分,年月日,年月,时分等格式。
——OptionsPickerView 选项选择器,支持一,二,三级选项选择,并且可以设置是否联动 。
支持三级联动
设置是否联动
设置循环模式
支持自定义布局。
支持item的分隔线设置。
支持item间距设置。
时间选择器支持起始和终止日期设定。
支持“年,月,日,时,分,秒”,“省,市,区”等选项的单位(label)显示、隐藏和自定义。
支持自定义文字、颜色、文字大小等属性
Item的文字长度过长时,文字会自适应缩放到Item的长度,避免显示不完全的问题
支持Dialog 模式。
支持自定义设置容器。
实时回调。
PickerView地址
首先先将库依赖到自己的项目中;
compile 'com.contrarywind:Android-PickerView:4.1.6'
先来看时间选择器,时间选择器涉及到TimePickerView和TimePickerBuilder,这里采用了链式编程和build设计模式;在TimePickerBuilder中提供了一系列调用设置的方法;
public class TimePickerBuilder {
private PickerOptions mPickerOptions;
//Required
public TimePickerBuilder(Context context, OnTimeSelectListener listener) {
mPickerOptions = new PickerOptions(PickerOptions.TYPE_PICKER_TIME);
mPickerOptions.context = context;
mPickerOptions.timeSelectListener = listener;
}
/**
* 设置位置
* @param gravity
* @return
*/
public TimePickerBuilder setGravity(int gravity) {
mPickerOptions.textGravity = gravity;
return this;
}
/**
* new boolean[]{true, true, true, false, false, false}
* control the "year","month","day","hours","minutes","seconds " display or hide.
* 分别控制“年”“月”“日”“时”“分”“秒”的显示或隐藏。
*
* @param type 布尔型数组,长度需要设置为6。
* @return TimePickerBuilder
*/
public TimePickerBuilder setType(boolean[] type) {
mPickerOptions.type = type;
return this;
}
/**
* 设置提交文字
* @param textContentConfirm
* @return
*/
public TimePickerBuilder setSubmitText(String textContentConfirm) {
mPickerOptions.textContentConfirm = textContentConfirm;
return this;
}
/**
* 是否是dialog
* @param isDialog
* @return
*/
public TimePickerBuilder isDialog(boolean isDialog) {
mPickerOptions.isDialog = isDialog;
return this;
}
/**
* 设置取消文字
* @param textContentCancel
* @return
*/
public TimePickerBuilder setCancelText(String textContentCancel) {
mPickerOptions.textContentCancel = textContentCancel;
return this;
}
/**
* 设置标题文字
* @param textContentTitle
* @return
*/
public TimePickerBuilder setTitleText(String textContentTitle) {
mPickerOptions.textContentTitle = textContentTitle;
return this;
}
/**
* 设置提交文字颜色
* @param textColorConfirm
* @return
*/
public TimePickerBuilder setSubmitColor(int textColorConfirm) {
mPickerOptions.textColorConfirm = textColorConfirm;
return this;
}
/**
* 设置取消文字颜色
* @param textColorCancel
* @return
*/
public TimePickerBuilder setCancelColor(int textColorCancel) {
mPickerOptions.textColorCancel = textColorCancel;
return this;
}
/**
* ViewGroup 类型的容器
*
* @param decorView 选择器会被添加到此容器中
* @return TimePickerBuilder
*/
public TimePickerBuilder setDecorView(ViewGroup decorView) {
mPickerOptions.decorView = decorView;
return this;
}
/**
* 设置背景颜色
* @param bgColorWheel
* @return
*/
public TimePickerBuilder setBgColor(int bgColorWheel) {
mPickerOptions.bgColorWheel = bgColorWheel;
return this;
}
/**
* 设置标题背景颜色
* @param bgColorTitle
* @return
*/
public TimePickerBuilder setTitleBgColor(int bgColorTitle) {
mPickerOptions.bgColorTitle = bgColorTitle;
return this;
}
/**
* 设置标题颜色
* @param textColorTitle
* @return
*/
public TimePickerBuilder setTitleColor(int textColorTitle) {
mPickerOptions.textColorTitle = textColorTitle;
return this;
}
public TimePickerBuilder setSubCalSize(int textSizeSubmitCancel) {
mPickerOptions.textSizeSubmitCancel = textSizeSubmitCancel;
return this;
}
/**
* 设置标题文字大小
* @param textSizeTitle
* @return
*/
public TimePickerBuilder setTitleSize(int textSizeTitle) {
mPickerOptions.textSizeTitle = textSizeTitle;
return this;
}
/**
* 设置当前文字大小
* @param textSizeContent
* @return
*/
public TimePickerBuilder setContentTextSize(int textSizeContent) {
mPickerOptions.textSizeContent = textSizeContent;
return this;
}
/**
* 因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11
*
* @param date
* @return TimePickerBuilder
*/
public TimePickerBuilder setDate(Calendar date) {
mPickerOptions.date = date;
return this;
}
/**
* 设置自定义布局
* @param res 资源布局id
* @param customListener 设置自定义布局回调
* @return
*/
public TimePickerBuilder setLayoutRes(int res, CustomListener customListener) {
mPickerOptions.layoutRes = res;
mPickerOptions.customListener = customListener;
return this;
}
/**
* 设置起始时间
* 因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11
*/
public TimePickerBuilder setRangDate(Calendar startDate, Calendar endDate) {
mPickerOptions.startDate = startDate;
mPickerOptions.endDate = endDate;
return this;
}
/**
* 设置间距倍数,但是只能在1.0-4.0f之间
*
* @param lineSpacingMultiplier
*/
public TimePickerBuilder setLineSpacingMultiplier(float lineSpacingMultiplier) {
mPickerOptions.lineSpacingMultiplier = lineSpacingMultiplier;
return this;
}
/**
* 设置分割线的颜色
*
* @param dividerColor
*/
public TimePickerBuilder setDividerColor(int dividerColor) {
mPickerOptions.dividerColor = dividerColor;
return this;
}
/**
* 设置分割线的类型
*
* @param dividerType
*/
public TimePickerBuilder setDividerType(WheelView.DividerType dividerType) {
mPickerOptions.dividerType = dividerType;
return this;
}
/**
* //显示时的外部背景色颜色,默认是灰色
*
* @param backgroundId
*/
public TimePickerBuilder setBackgroundId(int backgroundId) {
mPickerOptions.backgroundId = backgroundId;
return this;
}
/**
* 设置分割线之间的文字的颜色
*
* @param textColorCenter
*/
public TimePickerBuilder setTextColorCenter(int textColorCenter) {
mPickerOptions.textColorCenter = textColorCenter;
return this;
}
/**
* 设置分割线以外文字的颜色
*
* @param textColorOut
*/
public TimePickerBuilder setTextColorOut(int textColorOut) {
mPickerOptions.textColorOut = textColorOut;
return this;
}
public TimePickerBuilder isCyclic(boolean cyclic) {
mPickerOptions.cyclic = cyclic;
return this;
}
/**
* 点击外部区域是否隐藏
* @param cancelable
* @return
*/
public TimePickerBuilder setOutSideCancelable(boolean cancelable) {
mPickerOptions.cancelable = cancelable;
return this;
}
public TimePickerBuilder setLunarCalendar(boolean lunarCalendar) {
mPickerOptions.isLunarCalendar = lunarCalendar;
return this;
}
public TimePickerBuilder setLabel(String label_year, String label_month, String label_day, String label_hours, String label_mins, String label_seconds) {
mPickerOptions.label_year = label_year;
mPickerOptions.label_month = label_month;
mPickerOptions.label_day = label_day;
mPickerOptions.label_hours = label_hours;
mPickerOptions.label_minutes = label_mins;
mPickerOptions.label_seconds = label_seconds;
return this;
}
/**
* 设置X轴倾斜角度[ -90 , 90°]
*
* @param x_offset_year 年
* @param x_offset_month 月
* @param x_offset_day 日
* @param x_offset_hours 时
* @param x_offset_minutes 分
* @param x_offset_seconds 秒
* @return
*/
public TimePickerBuilder setTextXOffset(int x_offset_year, int x_offset_month, int x_offset_day,
int x_offset_hours, int x_offset_minutes, int x_offset_seconds) {
mPickerOptions.x_offset_year = x_offset_year;
mPickerOptions.x_offset_month = x_offset_month;
mPickerOptions.x_offset_day = x_offset_day;
mPickerOptions.x_offset_hours = x_offset_hours;
mPickerOptions.x_offset_minutes = x_offset_minutes;
mPickerOptions.x_offset_seconds = x_offset_seconds;
return this;
}
public TimePickerBuilder isCenterLabel(boolean isCenterLabel) {
mPickerOptions.isCenterLabel = isCenterLabel;
return this;
}
/**
* @param listener 切换item项滚动停止时,实时回调监听。
* @return
*/
public TimePickerBuilder setTimeSelectChangeListener(OnTimeSelectChangeListener listener) {
mPickerOptions.timeSelectChangeListener = listener;
return this;
}
/**
* 调用build方法构建TimePickerView对象
* @return
*/
public TimePickerView build() {
return new TimePickerView(mPickerOptions);
}
}
在实例化时可以根据自己需要调用相应方法;先看下非自定义布局的实现;
/**
* 初始化时间滚轮控件
*/
private void initTimePicker() {
pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date, View v) {
//选择回调
Toast.makeText(MainActivity.this,getTime(date),Toast.LENGTH_LONG).show();
}
})
.setTimeSelectChangeListener(new OnTimeSelectChangeListener() {
@Override
public void onTimeSelectChanged(Date date) {
//时间滚动监控回调
Log.e("pvTime-->",getTime(date));
}
})
.setType(new boolean[]{true, true, true, true, true, true,})
.isDialog(true)//默认设置false ,内部实现将DecorView 作为它的父控件。
.build();
Dialog dialog = pvTime.getDialog();
if(dialog!=null){
FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM
);
params.leftMargin=0;
params.rightMargin=0;
pvTime.getDialogContainerLayout().setLayoutParams(params);
Window dialogWindow = dialog.getWindow();
if(dialogWindow!=null){
//修改动画样式
dialogWindow.setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim);
//改成Bottom,底部显示
dialogWindow.setGravity(Gravity.BOTTOM);
}
}
}
调用上面这段代码,再调用show方法,效果就出来了;
公农历切换效果:
/**
* 初始化时间选择器 公农历切换
* 时间范围(1900-2100)
*/
private void initLunarPicker() {
//系统当前时间
Calendar selectedDate = Calendar.getInstance();
//开始时间
Calendar startDate = Calendar.getInstance();
startDate.set(1900, 1, 01);
//结束时间
Calendar endDate = Calendar.getInstance();
endDate.set(2100, 2, 28);
//时间选择器 自定义布局
pvCustomLunar = new TimePickerBuilder(this, new OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date, View v) {
String time = getTime(date);
//选中事件回调
Toast.makeText(MainActivity.this, time, Toast.LENGTH_LONG).show();
}
})
.setDate(selectedDate)//设置选中的时间为系统当前时间
.setRangDate(startDate, endDate)//设置时间返回
.setLayoutRes(R.layout.pickerview_custom_lunar, new CustomListener() {
@Override
public void customLayout(final View v) {
//通过setLayoutRes设置自定义布局效果
//在customLayout中进行逻辑处理
//完成
TextView tvFinish = v.findViewById(R.id.tv_finish);
tvFinish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击完成调用returnData方法会触发onTimeSelect进行回调
pvCustomLunar.returnData();
//隐藏布局
pvCustomLunar.dismiss();
}
});
//取消
ImageView ivCancel = v.findViewById(R.id.iv_cancel);
ivCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//隐藏布局
pvCustomLunar.dismiss();
}
});
//切换农历
CheckBox cbLunar = v.findViewById(R.id.cb_lunar);
cbLunar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
pvCustomLunar.setLunarCalendar(!pvCustomLunar.isLunarCalendar());
//自适应宽
setTimePickerChildWeight(v, isChecked ? 0.8f : 1f, isChecked ? 1f : 1.1f);
}
});
}
})
.setType(new boolean[]{true, true, true, false, false, false})//boolean数组,设置条码显示 true显示,false隐藏
.isCenterLabel(false)
.setDividerColor(Color.RED)//设置分割线颜色
.build();
}
/**
* 公农历切换后调整宽
*
* @param v
* @param yearWeight
* @param weight
*/
private void setTimePickerChildWeight(View v, float yearWeight, float weight) {
ViewGroup timePicker = (ViewGroup) v.findViewById(R.id.timepicker);
View year = timePicker.getChildAt(0);
LinearLayout.LayoutParams lp = ((LinearLayout.LayoutParams) year.getLayoutParams());
lp.weight = yearWeight;
year.setLayoutParams(lp);
for (int i = 1; i < timePicker.getChildCount(); i++) {
View childAt = timePicker.getChildAt(i);
LinearLayout.LayoutParams childLp = ((LinearLayout.LayoutParams) childAt.getLayoutParams());
childLp.weight = weight;
childAt.setLayoutParams(childLp);
}
}
自定义时间选择器布局效果:
/**
* @description
*
* 注意事项:
* 1.自定义布局中,id为 optionspicker 或者 timepicker 的布局以及其子控件必须要有,否则会报空指针.
* 具体可参考demo 里面的两个自定义layout布局。
* 2.因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11
* setRangDate方法控制起始终止时间(如果不设置范围,则使用默认时间1900-2100年,此段代码可注释)
*/
Calendar selectedDate = Calendar.getInstance();//系统当前时间
Calendar startDate = Calendar.getInstance();
startDate.set(2014, 1, 23);
Calendar endDate = Calendar.getInstance();
endDate.set(2027, 2, 28);
//时间选择器 ,自定义布局
pvCustomTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date, View v) {//选中事件回调
btnCustomTime.setText(getTime(date));
}
})
.setDate(selectedDate)
.setRangDate(startDate, endDate)
.setLayoutRes(R.layout.pickerview_custom_time, new CustomListener() {
@Override
public void customLayout(View v) {
final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
ImageView ivCancel = (ImageView) v.findViewById(R.id.iv_cancel);
tvSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pvCustomTime.returnData();
pvCustomTime.dismiss();
}
});
ivCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pvCustomTime.dismiss();
}
});
}
})
.setContentTextSize(18)
.setType(new boolean[]{false, false, false, true, true, true})
.setLabel("年", "月", "日", "时", "分", "秒")
.setLineSpacingMultiplier(1.2f)
.setTextXOffset(0, 0, 0, 40, 0, -40)
.isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
.setDividerColor(0xFF24AD9D)
.build();
}
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_height="50dp"
android:background="#EEEEEE">
android:layout_height="0.5dp"
android:background="#aaa" />
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_marginLeft="17dp"
android:padding="8dp"
android:src="@mipmap/to_down" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="17dp"
android:padding="8dp"
android:text="完成"
android:textColor="#24AD9D"
android:textSize="18sp" />
android:layout_height="0.5dp"
android:background="#aaa" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="horizontal">
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />
接下来看下条件选择器的大致使用,条件选择器实例化时主要涉及到OptionsPickerView和OptionsPickerBuilder,和时间选择器一样采用链式编程和build设计模式;
public class OptionsPickerBuilder {
//配置类
private PickerOptions mPickerOptions;
//Required
public OptionsPickerBuilder(Context context, OnOptionsSelectListener listener) {
mPickerOptions = new PickerOptions(PickerOptions.TYPE_PICKER_OPTIONS);
mPickerOptions.context = context;
mPickerOptions.optionsSelectListener = listener;
}
//Option
public OptionsPickerBuilder setSubmitText(String textContentConfirm) {
mPickerOptions.textContentConfirm = textContentConfirm;
return this;
}
public OptionsPickerBuilder setCancelText(String textContentCancel) {
mPickerOptions.textContentCancel = textContentCancel;
return this;
}
public OptionsPickerBuilder setTitleText(String textContentTitle) {
mPickerOptions.textContentTitle = textContentTitle;
return this;
}
public OptionsPickerBuilder isDialog(boolean isDialog) {
mPickerOptions.isDialog = isDialog;
return this;
}
public OptionsPickerBuilder setSubmitColor(int textColorConfirm) {
mPickerOptions.textColorConfirm = textColorConfirm;
return this;
}
public OptionsPickerBuilder setCancelColor(int textColorCancel) {
mPickerOptions.textColorCancel = textColorCancel;
return this;
}
/**
* 显示时的外部背景色颜色,默认是灰色
*
* @param backgroundId color resId.
* @return
*/
public OptionsPickerBuilder setBackgroundId(int backgroundId) {
mPickerOptions.backgroundId = backgroundId;
return this;
}
/**
* ViewGroup 类型
* 设置PickerView的显示容器
*
* @param decorView Parent View.
* @return
*/
public OptionsPickerBuilder setDecorView(ViewGroup decorView) {
mPickerOptions.decorView = decorView;
return this;
}
public OptionsPickerBuilder setLayoutRes(int res, CustomListener listener) {
mPickerOptions.layoutRes = res;
mPickerOptions.customListener = listener;
return this;
}
public OptionsPickerBuilder setBgColor(int bgColorWheel) {
mPickerOptions.bgColorWheel = bgColorWheel;
return this;
}
public OptionsPickerBuilder setTitleBgColor(int bgColorTitle) {
mPickerOptions.bgColorTitle = bgColorTitle;
return this;
}
public OptionsPickerBuilder setTitleColor(int textColorTitle) {
mPickerOptions.textColorTitle = textColorTitle;
return this;
}
public OptionsPickerBuilder setSubCalSize(int textSizeSubmitCancel) {
mPickerOptions.textSizeSubmitCancel = textSizeSubmitCancel;
return this;
}
public OptionsPickerBuilder setTitleSize(int textSizeTitle) {
mPickerOptions.textSizeTitle = textSizeTitle;
return this;
}
public OptionsPickerBuilder setContentTextSize(int textSizeContent) {
mPickerOptions.textSizeContent = textSizeContent;
return this;
}
public OptionsPickerBuilder setOutSideCancelable(boolean cancelable) {
mPickerOptions.cancelable = cancelable;
return this;
}
public OptionsPickerBuilder setLabels(String label1, String label2, String label3) {
mPickerOptions.label1 = label1;
mPickerOptions.label2 = label2;
mPickerOptions.label3 = label3;
return this;
}
/**
* 设置Item 的间距倍数,用于控制 Item 高度间隔
*
* @param lineSpacingMultiplier 浮点型,1.0-4.0f 之间有效,超过则取极值。
*/
public OptionsPickerBuilder setLineSpacingMultiplier(float lineSpacingMultiplier) {
mPickerOptions.lineSpacingMultiplier = lineSpacingMultiplier;
return this;
}
/**
* Set item divider line type color.
*
* @param dividerColor color resId.
*/
public OptionsPickerBuilder setDividerColor(int dividerColor) {
mPickerOptions.dividerColor = dividerColor;
return this;
}
/**
* Set item divider line type.
*
* @param dividerType enum Type {@link WheelView.DividerType}
*/
public OptionsPickerBuilder setDividerType(WheelView.DividerType dividerType) {
mPickerOptions.dividerType = dividerType;
return this;
}
/**
* Set the textColor of selected item.
*
* @param textColorCenter color res.
*/
public OptionsPickerBuilder setTextColorCenter(int textColorCenter) {
mPickerOptions.textColorCenter = textColorCenter;
return this;
}
/**
* Set the textColor of outside item.
*
* @param textColorOut color resId.
*/
public OptionsPickerBuilder setTextColorOut(int textColorOut) {
mPickerOptions.textColorOut = textColorOut;
return this;
}
public OptionsPickerBuilder setTypeface(Typeface font) {
mPickerOptions.font = font;
return this;
}
public OptionsPickerBuilder setCyclic(boolean cyclic1, boolean cyclic2, boolean cyclic3) {
mPickerOptions.cyclic1 = cyclic1;
mPickerOptions.cyclic2 = cyclic2;
mPickerOptions.cyclic3 = cyclic3;
return this;
}
public OptionsPickerBuilder setSelectOptions(int option1) {
mPickerOptions.option1 = option1;
return this;
}
public OptionsPickerBuilder setSelectOptions(int option1, int option2) {
mPickerOptions.option1 = option1;
mPickerOptions.option2 = option2;
return this;
}
public OptionsPickerBuilder setSelectOptions(int option1, int option2, int option3) {
mPickerOptions.option1 = option1;
mPickerOptions.option2 = option2;
mPickerOptions.option3 = option3;
return this;
}
public OptionsPickerBuilder setTextXOffset(int xoffset_one, int xoffset_two, int xoffset_three) {
mPickerOptions.x_offset_one = xoffset_one;
mPickerOptions.x_offset_two = xoffset_two;
mPickerOptions.x_offset_three = xoffset_three;
return this;
}
public OptionsPickerBuilder isCenterLabel(boolean isCenterLabel) {
mPickerOptions.isCenterLabel = isCenterLabel;
return this;
}
/**
* 切换选项时,是否还原第一项
*
* @param isRestoreItem true:还原; false: 保持上一个选项
* @return TimePickerBuilder
*/
public OptionsPickerBuilder isRestoreItem(boolean isRestoreItem) {
mPickerOptions.isRestoreItem = isRestoreItem;
return this;
}
/**
* @param listener 切换item项滚动停止时,实时回调监听。
* @return
*/
public OptionsPickerBuilder setOptionsSelectChangeListener(OnOptionsSelectChangeListener listener) {
mPickerOptions.optionsSelectChangeListener = listener;
return this;
}
public
return new OptionsPickerView<>(mPickerOptions);
}
}
OptionsPickerBuilder提供了一系列设置方法;根据效果的需要调用相应的方法;
先看一般的条件选择器的效果:
/**
* 初始化条件选择器
*/
private void initOptionPicker(){
pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
//返回的分别是三个级别的选中位置
String tx = options1Items.get(options1).getPickerViewText()
+ options2Items.get(options1).get(options2);
btnOptions.setText(tx);
}
})
.setTitleText("城市选择")//设置标题
.setContentTextSize(20)//设置滚轮文字大小
.setDividerColor(Color.LTGRAY)//设置分割线的颜色
.setSelectOptions(0, 1)//默认选中项
.setBgColor(Color.BLACK)//设置背景色
.setTitleBgColor(Color.DKGRAY)//设置标题背景色
.setTitleColor(Color.LTGRAY)//设置标题颜色
.setCancelColor(Color.YELLOW)//设置取消字体颜色
.setSubmitColor(Color.YELLOW)//设置提交字体颜色
.setTextColorCenter(Color.LTGRAY)//设置中间字体颜色
.isRestoreItem(true)//切换时是否还原,设置默认选中第一项。
.isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
.setLabels("省", "市", "区")
.setBackgroundId(0x00000000) //设置外部遮罩颜色
.setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
@Override
public void onOptionsSelectChanged(int options1, int options2, int options3) {
String str = "options1: " + options1 + "\noptions2: " + options2 + "\noptions3: " + options3;
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
})
.build();
// pvOptions.setSelectOptions(1,1);
/*pvOptions.setPicker(options1Items);//一级选择器*/
pvOptions.setPicker(options1Items, options2Items);//二级选择器
/*pvOptions.setPicker(options1Items, options2Items,options3Items);//三级选择器*/
}
条件选择器自定义布局效果:
/**
* 条件选择器初始化,自定义布局
*/
private void initCustomOptionPicker() {
/**
* @description
*
* 注意事项:
* 自定义布局中,id为 optionspicker 或者 timepicker 的布局以及其子控件必须要有,否则会报空指针。
* 具体可参考demo 里面的两个自定义layout布局。
*/
pvCustomOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3, View v) {
//返回的分别是三个级别的选中位置
String tx = cardItem.get(options1).getPickerViewText();
btnCustomOptions.setText(tx);
}
})
.setLayoutRes(R.layout.pickerview_custom_options, new CustomListener() {
@Override
public void customLayout(View v) {
final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
final TextView tvAdd = (TextView) v.findViewById(R.id.tv_add);
ImageView ivCancel = (ImageView) v.findViewById(R.id.iv_cancel);
tvSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pvCustomOptions.returnData();
pvCustomOptions.dismiss();
}
});
ivCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pvCustomOptions.dismiss();
}
});
tvAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getCardData();
pvCustomOptions.setPicker(cardItem);
}
});
}
})
.isDialog(true)
.build();
pvCustomOptions.setPicker(cardItem);//添加数据
}
条件选择(不联动效果):
/**
* 不联动的多级选项
*/
private void initNoLinkOptionsPicker() {
pvNoLinkOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
String str = "food:" + food.get(options1)
+ "\nclothes:" + clothes.get(options2)
+ "\ncomputer:" + computer.get(options3);
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
})
.setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
@Override
public void onOptionsSelectChanged(int options1, int options2, int options3) {
String str = "options1: " + options1 + "\noptions2: " + options2 + "\noptions3: " + options3;
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
})
// .setSelectOptions(0, 1, 1)
.build();
pvNoLinkOptions.setNPicker(food, clothes, computer);
pvNoLinkOptions.setSelectOptions(0, 1, 1);
}
最后来看下城市地址选择效果的实现:
public class JsonDataActivity extends AppCompatActivity implements View.OnClickListener {
private ArrayList
private ArrayList
private ArrayList
private Thread thread;
private static final int MSG_LOAD_DATA = 0x0001;
private static final int MSG_LOAD_SUCCESS = 0x0002;
private static final int MSG_LOAD_FAILED = 0x0003;
private boolean isLoaded = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json_data);
initView();
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_LOAD_DATA:
if (thread == null) {//如果已创建就不再重新创建子线程了
Toast.makeText(JsonDataActivity.this, "Begin Parse Data", Toast.LENGTH_SHORT).show();
thread = new Thread(new Runnable() {
@Override
public void run() {
// 子线程中解析省市区数据
initJsonData();
}
});
thread.start();
}
break;
case MSG_LOAD_SUCCESS:
Toast.makeText(JsonDataActivity.this, "Parse Succeed", Toast.LENGTH_SHORT).show();
isLoaded = true;
break;
case MSG_LOAD_FAILED:
Toast.makeText(JsonDataActivity.this, "Parse Failed", Toast.LENGTH_SHORT).show();
break;
}
}
};
private void initView() {
findViewById(R.id.btn_data).setOnClickListener(this);
findViewById(R.id.btn_show).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_data:
mHandler.sendEmptyMessage(MSG_LOAD_DATA);
break;
case R.id.btn_show:
if (isLoaded) {
showPickerView();
} else {
Toast.makeText(JsonDataActivity.this, "Please waiting until the data is parsed", Toast.LENGTH_SHORT).show();
}
break;
}
}
private void showPickerView() {// 弹出选择器
OptionsPickerView pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
//返回的分别是三个级别的选中位置
String tx = options1Items.get(options1).getPickerViewText() +
options2Items.get(options1).get(options2) +
options3Items.get(options1).get(options2).get(options3);
Toast.makeText(JsonDataActivity.this, tx, Toast.LENGTH_SHORT).show();
}
})
.setTitleText("城市选择")
.setDividerColor(Color.BLACK)
.setTextColorCenter(Color.BLACK) //设置选中项文字颜色
.setContentTextSize(20)
.build();
/*pvOptions.setPicker(options1Items);//一级选择器
pvOptions.setPicker(options1Items, options2Items);//二级选择器*/
pvOptions.setPicker(options1Items, options2Items, options3Items);//三级选择器
pvOptions.show();
}
private void initJsonData() {//解析数据
/**
* 注意:assets 目录下的Json文件仅供参考,实际使用可自行替换文件
* 关键逻辑在于循环体
*
* */
String JsonData = new GetJsonDataUtil().getJson(this, "province.json");//获取assets目录下的json文件数据
ArrayList
/**
* 添加省份数据
*
* 注意:如果是添加的JavaBean实体,则实体类需要实现 IPickerViewData 接口,
* PickerView会通过getPickerViewText方法获取字符串显示出来。
*/
options1Items = jsonBean;
for (int i = 0; i < jsonBean.size(); i++) {//遍历省份
ArrayList
ArrayList
for (int c = 0; c < jsonBean.get(i).getCityList().size(); c++) {//遍历该省份的所有城市
String CityName = jsonBean.get(i).getCityList().get(c).getName();
CityList.add(CityName);//添加城市
ArrayList
//如果无地区数据,建议添加空字符串,防止数据为null 导致三个选项长度不匹配造成崩溃
if (jsonBean.get(i).getCityList().get(c).getArea() == null
|| jsonBean.get(i).getCityList().get(c).getArea().size() == 0) {
City_AreaList.add("");
} else {
City_AreaList.addAll(jsonBean.get(i).getCityList().get(c).getArea());
}
Province_AreaList.add(City_AreaList);//添加该省所有地区数据
}
/**
* 添加城市数据
*/
options2Items.add(CityList);
/**
* 添加地区数据
*/
options3Items.add(Province_AreaList);
}
mHandler.sendEmptyMessage(MSG_LOAD_SUCCESS);
}
public ArrayList
ArrayList
try {
JSONArray data = new JSONArray(result);
Gson gson = new Gson();
for (int i = 0; i < data.length(); i++) {
JsonBean entity = gson.fromJson(data.optJSONObject(i).toString(), JsonBean.class);
detail.add(entity);
}
} catch (Exception e) {
e.printStackTrace();
mHandler.sendEmptyMessage(MSG_LOAD_FAILED);
}
return detail;
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mHandler != null) {
mHandler.removeCallbacksAndMessages(null);
}
}
}
源码地址
————————————————
版权声明:本文为CSDN博主「刘孙猫咪」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangwo1991/article/details/85036891