2016-03-24 18:01:51 QQ55214 阅读数 9513

ios的自带时间选择器很好看,但是android的自带时间选择器就各不相同,有的看起来还可以,但是有的就其丑无比,网上仿ios的自定义时间选择器 基本都是WheelView,上效果图吧,这是我修改过的结果。

          


/**
	 * 显示全部日期
	 */
	private void showDateAndTime(){

		Calendar c = Calendar.getInstance();
		int curYear = c.get(Calendar.YEAR);
		int curMonth = c.get(Calendar.MONTH) + 1;//通过Calendar算出的月数要+1
		int curDate = c.get(Calendar.DATE);

		final AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
				.create();
		dialog.show();
		Window window = dialog.getWindow();
		// 设置布局
		window.setContentView(R.layout.my_new_pop_layout);
		// 设置宽高
		window.setLayout(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
		// 设置弹出的动画效果
		window.setWindowAnimations(R.style.AnimBottom);

		month = (WheelView) window.findViewById(R.id.new_month);
		initMonth();
		day = (WheelView) window.findViewById(R.id.new_day);
		initDay(curYear,curMonth);
		hour = (WheelView) window.findViewById(R.id.new_hour);
		initHour();
		mins = (WheelView) window.findViewById(R.id.new_mins);
		initMins();

        // 设置当前时间
		//year.setCurrentItem(curYear - 1);
		month.setCurrentItem(curMonth - 1);
		day.setCurrentItem(curDate - 1);
		hour.setCurrentItem(8);
		mins.setCurrentItem(30);

		month.setVisibleItems(7);
		day.setVisibleItems(7);
		hour.setVisibleItems(7);
		mins.setVisibleItems(7);

		// 设置监听
		TextView ok = (TextView) window.findViewById(R.id.set);
		TextView cancel = (TextView) window.findViewById(R.id.cancel);
		ok.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String date = "2016" + "-"+ (month.getCurrentItem()+1)+"-"+(day.getCurrentItem()+1);
				String time = " " + hour.getCurrentItem()+ ":"+ (mins.getCurrentItem() + 1);
				Toast.makeText(MainActivity.this, date + time, Toast.LENGTH_LONG).show();
				dialog.cancel();
			}
		});
		cancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dialog.cancel();
			}
		});
		LinearLayout cancelLayout = (LinearLayout) window.findViewById(R.id.view_none);
		cancelLayout.setOnTouchListener(new View.OnTouchListener() {
			@Override
			public boolean onTouch(View view, MotionEvent motionEvent) {
				dialog.cancel();
				return false;
			}
		});
	}


	/**
	 * 显示时间
	 */
	private void showTimeDialog(){
		final AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
				.create();
		dialog.show();
		Window window = dialog.getWindow();
		// 设置布局
		window.setContentView(R.layout.timepick);
		// 设置宽高
		window.setLayout(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
		// 设置弹出的动画效果
		window.setWindowAnimations(R.style.AnimBottom);

		hour = (WheelView) window.findViewById(R.id.hour);
		initHour();
		mins = (WheelView) window.findViewById(R.id.mins);
		initMins();
		// 设置当前时间
		hour.setCurrentItem(8);
		mins.setCurrentItem(30);
		hour.setVisibleItems(7);
		mins.setVisibleItems(7);

		// 设置监听
		Button ok = (Button) window.findViewById(R.id.set);
		Button cancel = (Button) window.findViewById(R.id.cancel);
		ok.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String str = hour.getCurrentItem() + ":"+ mins.getCurrentItem();
				Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
				dialog.cancel();
			}
		});
		cancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dialog.cancel();
			}
		});
		LinearLayout cancelLayout = (LinearLayout) window.findViewById(R.id.view_none);
		cancelLayout.setOnTouchListener(new View.OnTouchListener() {
			@Override
			public boolean onTouch(View view, MotionEvent motionEvent) {
				dialog.cancel();
				return false;
			}
		});
	}


	/**
	 * 显示日期
	 */
	private void showDateDialog() {
		final AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
				.create();
		dialog.show();
		Window window = dialog.getWindow();
		// 设置布局
		window.setContentView(R.layout.datapick);
		// 设置宽高
		window.setLayout(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
		// 设置弹出的动画效果
		window.setWindowAnimations(R.style.AnimBottom);


		Calendar c = Calendar.getInstance();
		int curYear = c.get(Calendar.YEAR);
		int curMonth = c.get(Calendar.MONTH) + 1;//通过Calendar算出的月数要+1
		int curDate = c.get(Calendar.DATE);
		year = (WheelView) window.findViewById(R.id.year);
		initYear(curYear);
		month = (WheelView) window.findViewById(R.id.month);
		initMonth();
		day = (WheelView) window.findViewById(R.id.day);
		initDay(curYear,curMonth);


		year.setCurrentItem(curYear - 1950);
		month.setCurrentItem(curMonth - 1);
		day.setCurrentItem(curDate - 1);
		year.setVisibleItems(7);
		month.setVisibleItems(7);
		day.setVisibleItems(7);

		// 设置监听
		Button ok = (Button) window.findViewById(R.id.set);
		Button cancel = (Button) window.findViewById(R.id.cancel);
		ok.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String str = (year.getCurrentItem()+1950) + "-"+ (month.getCurrentItem()+1)+"-"+(day.getCurrentItem()+1);
				Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
				dialog.cancel();
			}
		});
		cancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dialog.cancel();
			}
		});
		LinearLayout cancelLayout = (LinearLayout) window.findViewById(R.id.view_none);
		cancelLayout.setOnTouchListener(new View.OnTouchListener() {
			@Override
			public boolean onTouch(View view, MotionEvent motionEvent) {
				dialog.cancel();
				return false;
			}
		});
		// 因为我们用的是windows的方法,所以不管ok活cancel都要加上“dialog.cancel()”这句话,
		// 不然有程序崩溃的可能,仅仅是一种可能,但我们还是要排除这一点,对吧?
		// 用AlertDialog的两个Button,即使监听里什么也不写,点击后也是会吧dialog关掉的,不信的同学可以去试下

	}

/**
	 * 初始化年
	 */
	private void initYear(int curYear) {
		NumericWheelAdapter numericWheelAdapter = new NumericWheelAdapter(this,1950, curYear);
		numericWheelAdapter.setLabel(" 年");
		//		numericWheelAdapter.setTextSize(15);  设置字体大小
		year.setViewAdapter(numericWheelAdapter);
		year.setCyclic(true);
	}

	/**
	 * 初始化月
	 */
	private void initMonth() {
		NumericWheelAdapter numericWheelAdapter = new NumericWheelAdapter(this,1, 12, "%02d");
		numericWheelAdapter.setLabel(" 月");
		//		numericWheelAdapter.setTextSize(15);  设置字体大小
		month.setViewAdapter(numericWheelAdapter);
		month.setCyclic(true);
	}

	/**
	 * 初始化天
	 */
	private void initDay(int arg1, int arg2) {
		NumericWheelAdapter numericWheelAdapter=new NumericWheelAdapter(this,1, getDay(arg1, arg2), "%02d");
		numericWheelAdapter.setLabel(" 日");
		//		numericWheelAdapter.setTextSize(15);  设置字体大小
		day.setViewAdapter(numericWheelAdapter);
		day.setCyclic(true);
	}

	/**
	 * 初始化时
	 */
	private void initHour() {
		NumericWheelAdapter numericWheelAdapter = new NumericWheelAdapter(this,1, 23, "%02d");
		numericWheelAdapter.setLabel(" 时");
		//		numericWheelAdapter.setTextSize(15);  设置字体大小
		hour.setViewAdapter(numericWheelAdapter);
		hour.setCyclic(true);
	}

	/**
	 * 初始化分
	 */
	private void initMins() {
		NumericWheelAdapter numericWheelAdapter = new NumericWheelAdapter(this,1, 59, "%02d");
		numericWheelAdapter.setLabel(" 分");
//		numericWheelAdapter.setTextSize(15);  设置字体大小
		mins.setViewAdapter(numericWheelAdapter);
		mins.setCyclic(true);
	}


源码下载地址

http://download.csdn.net/detail/qq55214/9471688

2018-04-12 15:42:00 android410223Sun 阅读数 1392
可以自定义设置开始时间和结束时间,弹出时默认选中的时间,支持时分年月日等等,先看效果图吧,简单的main界面:

然后是各个样式的选择器 01:   年月选择器:

02:   年-月-日  时:分选择器:

03:   年-月-日 选择器

04:年-月  时:分 选择器 (这个可能不怎么用到,但我用到了  恶心。)


暂时就先实现了这几个效果,因为最后04:年-月  时:分 选择器这个我项目不需要设置默认时间所以代码里也只有他功能比较简单。

代码就不贴了,太多,我讲一下使用的方法

UIDateTimeActivity ui4 = new UIDateTimeActivity(this,DateAndTimeMenu.DATEYMHM,"2017-01-01 10:10","2018-06-08 11:11","2017-06-08 13:13");
ui4.show();
ui4.setCallBack(this);

构造里五个参数,当前activity的context,一个枚举常量(1-4四个数字代表四种选择器样式),开始时间,结束时间,默认时间。

setCallBack回调函数  在每个WhellView滑动的时候  都会实时回调选中的值,获取选中时间值的回调函数:

@Override
    public void sendSeledDateOrTime(String date_or_time) {
//        Toast.makeText(this,date_or_time,Toast.LENGTH_LONG).show();
    }

demo下载地址:https://download.csdn.net/download/android410223sun/10344090  (选择器的代码已经打成库在其中依赖了,可以自主修改)

2018-12-16 15:19:11 wangwo1991 阅读数 1645

在项目开发中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();
    }
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#EEEEEE">
        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="#aaa" />
        <ImageView
            android:id="@+id/iv_cancel"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="17dp"
            android:padding="8dp"
            android:src="@mipmap/to_down" />
        <TextView
            android:id="@+id/tv_finish"
            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" />
        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="#aaa" />
    </RelativeLayout>
    <!--此部分需要完整复制过去,删减或者更改ID会导致初始化找不到内容而报空-->
    <LinearLayout
        android:id="@+id/timepicker"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:orientation="horizontal">
        <com.contrarywind.view.WheelView
            android:id="@+id/year"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
        <com.contrarywind.view.WheelView
            android:id="@+id/month"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />
        <com.contrarywind.view.WheelView
            android:id="@+id/day"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />
        <com.contrarywind.view.WheelView
            android:id="@+id/hour"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />
        <com.contrarywind.view.WheelView
            android:id="@+id/min"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />
        <com.contrarywind.view.WheelView
            android:id="@+id/second"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />
    </LinearLayout>
</LinearLayout>

接下来看下条件选择器的大致使用,条件选择器实例化时主要涉及到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 <T> OptionsPickerView<T> build() {
        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<JsonBean> options1Items = new ArrayList<>();
    private ArrayList<ArrayList<String>> options2Items = new ArrayList<>();
    private ArrayList<ArrayList<ArrayList<String>>> options3Items = new 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<JsonBean> jsonBean = parseData(JsonData);//用Gson 转成实体

        /**
         * 添加省份数据
         *
         * 注意:如果是添加的JavaBean实体,则实体类需要实现 IPickerViewData 接口,
         * PickerView会通过getPickerViewText方法获取字符串显示出来。
         */
        options1Items = jsonBean;

        for (int i = 0; i < jsonBean.size(); i++) {//遍历省份
            ArrayList<String> CityList = new ArrayList<>();//该省的城市列表(第二级)
            ArrayList<ArrayList<String>> Province_AreaList = new 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<String> City_AreaList = new 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<JsonBean> parseData(String result) {//Gson 解析
        ArrayList<JsonBean> detail = new 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);
        }
    }
}

源码地址

2016-01-27 16:36:04 u014061684 阅读数 16799

Android  仿IOS3D时间选择器城市选择器  城市数据从数据库读取,可自由添加数据。







实现代码

package com.jock.pickerview;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

import com.jock.pickerview.dao.RegionDAO;
import com.jock.pickerview.view.OptionsPickerView;
import com.jock.pickerview.view.TimePickerView;

public class MainActivity extends Activity
{

	private TextView tvTime, tvOptions;
	TimePickerView pvTime;
	OptionsPickerView pvOptions;

	static ArrayList<RegionInfo> item1;

	static ArrayList<ArrayList<RegionInfo>> item2 = new ArrayList<ArrayList<RegionInfo>>();

	static ArrayList<ArrayList<ArrayList<RegionInfo>>> item3 = new ArrayList<ArrayList<ArrayList<RegionInfo>>>();

	private Handler handler = new Handler()
	{
		public void handleMessage(android.os.Message msg)
		{
			System.out.println(System.currentTimeMillis());
			// 三级联动效果

			pvOptions.setPicker(item1, item2, item3, true);
			pvOptions.setCyclic(true, true, true);
			pvOptions.setSelectOptions(0, 0, 0);
			tvOptions.setClickable(true);
		};
	};

	@SuppressWarnings("unchecked")
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		tvTime = (TextView) findViewById(R.id.tvTime);

		tvOptions = (TextView) findViewById(R.id.tvOptions);

		// 时间选择器
		pvTime = new TimePickerView(this, TimePickerView.Type.YEAR_MONTH_DAY);
		// 控制时间范围
//		 Calendar calendar = Calendar.getInstance();
//		 pvTime.setRange(calendar.get(Calendar.YEAR) - 20,
//		 calendar.get(Calendar.YEAR));
		pvTime.setTime(new Date());
		pvTime.setCyclic(false);
		pvTime.setCancelable(true);
		// 时间选择后回调
		pvTime.setOnTimeSelectListener(new TimePickerView.OnTimeSelectListener()
		{

			@Override
			public void onTimeSelect(Date date)
			{
				tvTime.setText(getTime(date));
			}
		});
		// 弹出时间选择器
		tvTime.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				pvTime.show();
			}
		});

		// 选项选择器
		pvOptions = new OptionsPickerView(this);

		new Thread(new Runnable()
		{

			@Override
			public void run()
			{
				// TODO Auto-generated method stub
				System.out.println(System.currentTimeMillis());
				if (item1 != null && item2 != null && item3 != null)
				{
					handler.sendEmptyMessage(0x123);
					return;
				}
				item1 = (ArrayList<RegionInfo>) RegionDAO.getProvencesOrCity(1);
				for (RegionInfo regionInfo : item1)
				{
					item2.add((ArrayList<RegionInfo>) RegionDAO.getProvencesOrCityOnParent(regionInfo.getId()));

				}

				for (ArrayList<RegionInfo> arrayList : item2)
				{
					ArrayList<ArrayList<RegionInfo>> list2 = new ArrayList<ArrayList<RegionInfo>>();
					for (RegionInfo regionInfo : arrayList)
					{

						

						ArrayList<RegionInfo> q = (ArrayList<RegionInfo>) RegionDAO.getProvencesOrCityOnParent(regionInfo.getId());
						list2.add(q);

					}
					item3.add(list2);
				}

				handler.sendEmptyMessage(0x123);

			}
		}).start();
		// 设置选择的三级单位
		// pwOptions.setLabels("省", "市", "区");
		pvOptions.setTitle("选择城市");

		// 设置默认选中的三级项目
		// 监听确定选择按钮

		pvOptions.setOnoptionsSelectListener(new OptionsPickerView.OnOptionsSelectListener()
		{

			@Override
			public void onOptionsSelect(int options1, int option2, int options3)
			{
				// 返回的分别是三个级别的选中位置
				String tx = item1.get(options1).getPickerViewText() + item2.get(options1).get(option2).getPickerViewText() + item3.get(options1).get(option2).get(options3).getPickerViewText();
				tvOptions.setText(tx);

			}
		});
		// 点击弹出选项选择器
		tvOptions.setOnClickListener(new View.OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				pvOptions.show();
			}
		});

		tvOptions.setClickable(false);
	}

	public static String getTime(Date date)
	{
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		return format.format(date);
	}

}

源码下载

2017-09-01 17:56:50 qq_38012469 阅读数 737

安卓开发-高仿ios时间选择控件timepicker

96
作者 庞哈哈哈12138
2017.06.20 15:36* 字数 514 阅读 715评论 0

在开发中如果有地址或者日期选择等就会涉及到时间或者条件选择器,大家都会想到仿iOS的三级联动的效果,用wheelview实现,其实安卓原生自带了时间和日期选择器可能是效果来说太粗犷了,所以很多产品效果图都是清一色的ios那种效果,ok,废话说完了上图











demo地址:https://github.com/PangHaHa12138/TimePackdemo

1,安卓原生的时间和日期选择器

代码:

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();

使用非常简单,自己写个时间过滤方法就行

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那种效果差不多,来回上下滑选择日期的,但是5.0后就成日历了,虽然好看,不过占比屏太大,设计并不会考虑这种效果,哎,现在很多安卓的控件原生其实效果不错的,不过还是得为了遵循产品和设计的意思做成仿ios效果(小小的抱怨一下)

2.开源日期选择器Timepickview和条件选择器Optionspickview

代码:timepick:

TimePickerView pvTime = new TimePickerView.Builder(MainActivity.this, new TimePickerView.OnTimeSelectListener() {
                    @Override
                    public void onTimeSelect(Date date2, View v) {//选中事件回调
                        String time = getTime(date2);
                       button3.setText(time);
                    }
                })
                        .setType(TimePickerView.Type.YEAR_MONTH_DAY)//默认全部显示
                        .setCancelText("取消")//取消按钮文字
                        .setSubmitText("确定")//确认按钮文字
                        .setContentSize(20)//滚轮文字大小
                        .setTitleSize(20)//标题文字大小
//                        .setTitleText("请选择时间")//标题文字
                        .setOutSideCancelable(true)//点击屏幕,点在控件外部范围时,是否取消显示
                        .isCyclic(true)//是否循环滚动
                        .setTextColorCenter(Color.BLACK)//设置选中项的颜色
                        .setTitleColor(Color.BLACK)//标题文字颜色
                        .setSubmitColor(Color.BLUE)//确定按钮文字颜色
                        .setCancelColor(Color.BLUE)//取消按钮文字颜色
//                        .setTitleBgColor(0xFF666666)//标题背景颜色 Night mode
//                        .setBgColor(0xFF333333)//滚轮背景颜色 Night mode
//                        .setRange(calendar.get(Calendar.YEAR) - 20, calendar.get(Calendar.YEAR) + 20)//默认是1900-2100年
//                        .setDate(selectedDate)// 如果不设置的话,默认是系统时间*/
//                        .setRangDate(startDate,endDate)//起始终止年月日设定
//                        .setLabel("年","月","日","时","分","秒")
                        .isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
//                        .isDialog(true)//是否显示为对话框样式
                        .build();
                pvTime.setDate(Calendar.getInstance());//注:根据需求来决定是否使用该方法(一般是精确到秒的情况),此项可以在弹出选择器的时候重新设置当前时间,避免在初始化之后由于时间已经设定,导致选中时间与当前时间不匹配的问题。
                pvTime.show();

注释已经写的很详细了,各种选项干嘛用的
Optionspickview:代码:

options1Items.clear();
options1Items.add("托儿索");
options1Items.add("儿童劫");
options1Items.add("小学生之手");
options1Items.add("德玛西亚大保健");
options1Items.add("面对疾风吧");
options1Items.add("天王盖地虎");
options1Items.add("我发一米五");
options1Items.add("爆刘继芬");

OptionsPickerView pvOptions = new  OptionsPickerView.Builder(MainActivity.this, new OptionsPickerView.OnOptionsSelectListener() {
                    @Override
                    public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
                        //返回的分别是三个级别的选中位置
                       String s =  options1Items.get(options1);
                        button4.setText(s);

                    }
                })
//                        .setSubmitText("确定")//确定按钮文字
//                        .setCancelText("取消")//取消按钮文字
//                        .setTitleText("城市选择")//标题
                        .setSubCalSize(20)//确定和取消文字大小
//                        .setTitleSize(20)//标题文字大小
//                        .setTitleColor(Color.BLACK)//标题文字颜色
                        .setSubmitColor(Color.BLUE)//确定按钮文字颜色
                        .setCancelColor(Color.BLUE)//取消按钮文字颜色
//                        .setTitleBgColor(0xFF333333)//标题背景颜色 Night mode
//                        .setBgColor(0xFF000000)//滚轮背景颜色 Night mode
//                        .setContentTextSize(18)//滚轮文字大小
//                        .setTextColorCenter(Color.BLUE)//设置选中项的颜色
                        .setTextColorCenter(Color.BLACK)//设置选中项的颜色
//                        .setLineSpacingMultiplier(1.6f)//设置两横线之间的间隔倍数
//                        .setLinkage(false)//设置是否联动,默认true
//                        .setLabels("省", "市", "区")//设置选择的三级单位
//                        .isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
//                        .setCyclic(false, false, false)//循环与否
//                        .setSelectOptions(1, 1, 1)  //设置默认选中项
//                        .setOutSideCancelable(false)//点击外部dismiss default true
//                        .isDialog(true)//是否显示为对话框样式
                        .build();
                pvOptions.setPicker(options1Items);
                pvOptions.show();

条件自己定义,可以传简单集合,也可以传别的,比如省市县…

3.结合wheelview和原生timepick自定义时间选择器

用法:

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]);

    }
});

大致思路:
年-月-日,其实是三个wheelview,然后手动设置时间的范围,继承原有的adapter
一个例子

* 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);    
        }
    }

还有设置滑动监听,改变日期

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里,设置时间

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+"";
}

/**
 * 设置年月日
 * 
 * @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);
}

/**
 * 设置年份
 * 
 * @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;
}

/**
 * 设置月份
 * 
 * @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;
}

/**
 * 计算每月多少天
 * 
 * @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();
   }

然后设置点击事件

@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();

}

其实就是点击确定保存选择的日期,取消dismiss
底下确定键是黄色按钮那个就是换了个样式而已原理都是一样的
感谢阅读:~have a nice day~
demo地址:https://github.com/PangHaHa12138/TimePackdemo

日记本

仿ios日期选择器

阅读数 1914

没有更多推荐了,返回首页