(九) 盘古UI,日期和时间选择控件,自定义多种场景!
盘古UI,较为全面的自定义UI框架,帮助你绝对的快速开发!(长期维护中)
控件位置:
主要控件: com.smart.pangu_ui_lib.widget.PanguSelectDateView
内部使用的时间弹窗:pop: com.smart.pangu_ui_lib.pop.PopSelectDate
demo地址,点击查看github
时间和日期选择器
时间日期选择器可以灵活设置选择模式,是年月日还是其他的模式,包含多种模式可选,可以支持双时间展示等,更多功能见demo!
1, 样例展示图
2, 使用说明
1,布局
<com.smart.pangu_ui_lib.widget.PanguSelectDateViewandroid:id="@+id/pg_date"android:layout_margin="18dp"app:pgsdate_hint_start="开始时间"app:pgsdate_hint_end="结束时间"app:pgsdate_must="true"app:pgsdate_select_mode="yyyy_MM_dd_HH_mm_ss"android:layout_width="match_parent"android:layout_height="wrap_content"app:pgsdate_title="选择出发时间" />
2,方法使用
mPgDate.setOnDateSureListener(new PanguSelectDateView.OnDateSureListener() {@Overridepublic boolean onSureClick(int type, PanguSelectView view, String currentSelectDate, long currentSelectDateMillis) {showToast("选中的时间 , "+currentSelectDate);//上次选择的时间long startTime = mPgDate.getStartTimeMillis();long endTime = mPgDate.getEndTimeMillis();if (type==0){//开始时间if (currentSelectDateMillis>System.currentTimeMillis()){showToast("请选择当前时间-之前-的时间 ");return true;}}if (type==1){//结束时间if (currentSelectDateMillis<System.currentTimeMillis()){showToast("请选择当前时间-之后-的时间 ");return true;}}return false;}});
3, 方法和属性说明
attr属性 | 方法 method | 介绍 introduction |
---|---|---|
pgsdate_select_mode | setDateSelectMode(int mode) | 日期选择形式 0,年; 1,年月日; 2,年月日时分;3,月日;4,时分;5年月日时分秒 |
pgsdate_show_mode | setDateShowMode(int mode) | 日期显示形式 1,显示一个日期 ; 2,显示两个日期 |
pgsdate_title | setTitle(String title) | 名称 |
pgsdate_hint_start | setHintStart(String hintStart) | 开始时间的提示 |
pgsdate_hint_end | setHintEnd(String hintEnd) | 结束时间的提示 |
pgsdate_enable | setEnable(boolean enable) | 是否可用 |
pgsdate_must | setIsMust(boolean must) | 必选 |
pgsdate_border | setBorder(boolean border) | 边框 |
pgsdate_title_color | setTitleColor(int titleColor) | 标题颜色 |
pgsdate_show_title | setTitleVisibility(int visibility) | 是否显示标题 |
---- | setSize(int width, int height) | 设置布局宽高 |
---- | int getDateSelectMode() | 日期选择形式 |
---- | String getDateTransFormat() | 获取时间转换格式 |
---- | setData(String name, String keyStart, String keyEnd) | 设置搜索条件名称和输入提示 |
---- | setStartTime(String t) | 设置开始时间 |
---- | setEndTime(String t) | 设置结束时间 |
---- | String getYear() | 获取年 |
---- | String getStartTime() | 获取开始时间 |
---- | String getEndTime() | 获取结束时间 |
---- | long getStartTimeMillis() | 获取开始时间 |
---- | long getEndTimeMillis() | 获取结束时间 |
---- | reset() | 重置 |
4, 代码和方法简析
1,PopSelectDate,时间的弹窗
/*** 本类的主要功能是 : wheelView的使用** @author jiang_zheng_yan 2020/4/7 17:27*/
public class PopSelectDate extends PanguBasePop {private static final String TAG = "PopWheelViewDemo";private LinearLayout mLlContainer;private WheelView mWvHour;private WheelView mWvMin;private TextView mTvYear;private TextView mTvMonth;private TextView mTvDay;private TextView mTvHour;private TextView mTvMin;private TextView mTvSecond;private TextView mTvCancel;private TextView mTvSure;private LinearLayout mLlPopRoot;private WheelView mWvYear;private WheelView mWvMonth;private WheelView mWvDay;private WheelView mWvSecond;private int year;private int month;private int day;private int hour;private int min;private int second;private static int startyear = 1900;private static int endyear = 2100;private int date_select_mode = 2;//0,年; 1,年月日; 2,年月日时分public PopSelectDate(Context context) {super(context);}@Overrideprotected int getContentViewId() {return R.layout.pop_select_date;}@Overridepublic void initData(View v, Context context) {mLlContainer = v.findViewById(R.id.ll_container);mWvHour = v.findViewById(R.id.wv_hour);mWvMin = v.findViewById(R.id.wv_min);mTvYear = v.findViewById(R.id.tv_year);mTvMonth = v.findViewById(R.id.tv_month);mTvDay = v.findViewById(R.id.tv_day);mTvHour = v.findViewById(R.id.tv_hour);mTvMin = v.findViewById(R.id.tv_min);mTvSecond = v.findViewById(R.id.tv_second);mTvCancel = v.findViewById(R.id.tv_cancel);mTvSure = v.findViewById(R.id.tv_sure);mLlPopRoot = v.findViewById(R.id.ll_pop_root);mWvYear = v.findViewById(R.id.wv_year);mWvMonth = v.findViewById(R.id.wv_month);mWvDay = v.findViewById(R.id.wv_day);mWvSecond = v.findViewById(R.id.wv_second);Calendar calendar = Calendar.getInstance();year = calendar.get(Calendar.YEAR);month = calendar.get(Calendar.MONTH) + 1;day = calendar.get(Calendar.DAY_OF_MONTH);hour = calendar.get(Calendar.HOUR_OF_DAY);min = calendar.get(Calendar.MINUTE);second = calendar.get(Calendar.SECOND);initListener();//动画setAnimaType(AnimaType.BOTTOM_IN_OUT);//设置日期数据setDateData();}private void initListener() {mTvSure.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {dismiss();if (onClickSureListener != null) {onClickSureListener.onClick(view);}Log.e(TAG, "onViewClicked: " + getSelectDate("yyyy*MM*dd"));}});mTvCancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {dismiss();if (onClickCancelListener != null) {onClickCancelListener.onClick(view);}}});}private void setDateData() {//年ArrayList<WheelData> years = new ArrayList<>();//月ArrayList<String> months = new ArrayList<>();//时ArrayList<String> hours = new ArrayList<>();//分ArrayList<String> mins = new ArrayList<>();//秒ArrayList<String> seconds = new ArrayList<>();for (int i = startyear; i <= endyear; i++) {WheelData wheelData = new WheelData();wheelData.setAge(i);wheelData.setName(i + "");years.add(wheelData);}for (int i = 1; i <= 12; i++) {months.add((i + "").length() == 1 ? "0" + i : i + "");}for (int i = 0; i < 24; i++) {hours.add((i + "").length() == 1 ? "0" + i : i + "");}for (int i = 0; i < 60; i++) {mins.add((i + "").length() == 1 ? "0" + i : i + "");}for (int i = 0; i < 60; i++) {seconds.add((i + "").length() == 1 ? "0" + i : i + "");}//年mWvYear.setAdapter(new BaseWheelAdapter<WheelData>(years));mWvYear.setCurrentItem(year - startyear);mWvYear.setCyclic(false);mWvYear.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(int index, Object item) {year = Integer.parseInt(((WheelData) item).getPickerViewText());mWvDay.setAdapter(new BaseWheelAdapter<String>(DateUtil.getDaysList(year, month)));}});//月mWvMonth.setAdapter(new BaseWheelAdapter<String>(months));mWvMonth.setCurrentItem(month - 1);mWvMonth.setCyclic(false);mWvMonth.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(int index, Object item) {month = index + 1;int preItemIndex = mWvDay.getCurrentItemIndex();ArrayList<String> daysList = DateUtil.getDaysList(year, month);if (preItemIndex + 1 > daysList.size()) {preItemIndex = daysList.size() - 1;}mWvDay.setAdapter(new BaseWheelAdapter<String>(daysList));//修复问题mWvDay.setCurrentItem(preItemIndex);}});//日mWvDay.setAdapter(new BaseWheelAdapter<String>(DateUtil.getDaysList(year, month)));mWvDay.setCurrentItem(day - 1);mWvDay.setCyclic(false);mWvDay.cancelFuture();//小时mWvHour.setAdapter(new BaseWheelAdapter<String>(hours));mWvHour.setCurrentItem(hour);mWvHour.setCyclic(false);mWvHour.cancelFuture();//分mWvMin.setAdapter(new BaseWheelAdapter<String>(mins));mWvMin.setCurrentItem(min);mWvMin.setCyclic(false);mWvMin.cancelFuture();//秒mWvSecond.setAdapter(new BaseWheelAdapter<String>(seconds));mWvSecond.setCurrentItem(second);mWvSecond.setCyclic(false);mWvSecond.cancelFuture();}/*** 获取选择的日期时间** @return*/public String getSelectDate(String format) {String originFormat = "yyyy-MM-dd HH:mm";
// 0,年; 1,年月日; 2,年月日时分 3,月日 4,时分 5,年月日时分秒String dateStr = year + "-" + month + "-" + mWvDay.getCurrentItem() + " " + mWvHour.getCurrentItem() + ":" + mWvMin.getCurrentItem() + ":" + mWvSecond.getCurrentItem();switch (date_select_mode) {case 0:dateStr = year + "";originFormat = "yyyy";break;case 1:dateStr = year + "-" + month + "-" + mWvDay.getCurrentItem();originFormat = "yyyy-MM-dd";break;case 2:dateStr = year + "-" + month + "-" + mWvDay.getCurrentItem() + " " + mWvHour.getCurrentItem() + ":" + mWvMin.getCurrentItem();originFormat = "yyyy-MM-dd HH:mm";break;case 3:dateStr = month + "-" + mWvDay.getCurrentItem();originFormat = "MM-dd";break;case 4:dateStr = mWvHour.getCurrentItem() + ":" + mWvMin.getCurrentItem();originFormat = "HH:mm";break;case 5:dateStr = year + "-" + month + "-" + mWvDay.getCurrentItem() + " " + mWvHour.getCurrentItem() + ":" + mWvMin.getCurrentItem() + ":" + mWvSecond.getCurrentItem();originFormat = "yyyy-MM-dd HH:mm:ss";break;}return DateUtil.translateDateStr(dateStr, originFormat, format);}/*** 日期选择形式** @param mode 0,年; 1,年月日; 2,年月日时分 3,月日 4,时分 5,年月日时分秒*/public void setDateSelectMode(int mode) {date_select_mode = mode;//显示年//显示月//显示日//显示时//显示分boolean showYear = mode == 0 || mode == 1 || mode == 2 || mode == 5;boolean showMonth = mode == 1 || mode == 2 || mode == 3 || mode == 5;boolean showDay = mode == 1 || mode == 2 || mode == 3 || mode == 5;boolean showHour = mode == 2 || mode == 4 || mode == 5;boolean showMin = mode == 2 || mode == 4 || mode == 5;boolean showSecond = mode == 5;mTvYear.setVisibility(showYear ? View.VISIBLE : View.GONE);mTvMonth.setVisibility(showMonth ? View.VISIBLE : View.GONE);mTvDay.setVisibility(showDay ? View.VISIBLE : View.GONE);mTvHour.setVisibility(showHour ? View.VISIBLE : View.GONE);mTvMin.setVisibility(showMin ? View.VISIBLE : View.GONE);mTvSecond.setVisibility(showSecond ? View.VISIBLE : View.GONE);mWvYear.setVisibility(showYear ? View.VISIBLE : View.GONE);mWvMonth.setVisibility(showMonth ? View.VISIBLE : View.GONE);mWvDay.setVisibility(showDay ? View.VISIBLE : View.GONE);mWvHour.setVisibility(showHour ? View.VISIBLE : View.GONE);mWvMin.setVisibility(showMin ? View.VISIBLE : View.GONE);mWvSecond.setVisibility(showSecond ? View.VISIBLE : View.GONE);}/*** 是否循环** @param isCylic*/public void setIsCylic(boolean isCylic) {mWvYear.setCyclic(isCylic);mWvMonth.setCyclic(isCylic);mWvDay.setCyclic(isCylic);mWvHour.setCyclic(isCylic);mWvMin.setCyclic(isCylic);}/*** 设置当前选中的日期** @param dateStr 日期* @param format 格式 yyyy-MM-dd HH:mm:ss*/public void setCurrentDate(String dateStr, String format) {if (TextUtils.isEmpty(format)) {return;}try {long dateTimeMillis = DateUtil.getDateTimeMillis(dateStr, format);Calendar calendar = Calendar.getInstance();calendar.setTime(dateTimeMillis == 0 ? new Date() : new Date(dateTimeMillis));year = calendar.get(Calendar.YEAR);month = calendar.get(Calendar.MONTH) + 1;day = calendar.get(Calendar.DAY_OF_MONTH);hour = calendar.get(Calendar.HOUR_OF_DAY);min = calendar.get(Calendar.MINUTE);second = calendar.get(Calendar.SECOND);setDateData();} catch (Exception e) {Log.e(TAG, "setCurrentDate: 设置当前日期异常");}}// 设置wheelview 的数据实体(除 string int)需要实现 IPickerViewDatastatic class WheelData implements PickerViewData {private String name;private int age;@Overridepublic String getPickerViewText() {return name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
}
2,PanguSelectDateView,时间控件,内部时间弹窗使用的是PopSelectDate
/*** 本类的主要功能是 :时间控件** @author jiangzhengyan 2024/4/19 15:00*/
public class PanguSelectDateView extends BaseView {private LinearLayout mRoot;private PanguSelectView mCsvStartDate;private ImageView mIvArrow;private PanguSelectView mCsvEndDate;private String keyStart;private String keyEnd;private int csdate_select_mode;private int csdate_show_mode;private String title;private String hintStart;private String hintEnd;private boolean enable;private boolean must;private int showTitle;public PanguSelectDateView(Context context) {super(context);}public PanguSelectDateView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected int getLayoutId() {return R.layout.pangu_select_date_view;}@Overrideprotected void initView(Context context, AttributeSet attrs, int defStyleAttr) {mRoot = findViewById(R.id.root);mCsvStartDate = findViewById(R.id.csv_start_date);mIvArrow = findViewById(R.id.iv_arrow);mCsvEndDate = findViewById(R.id.csv_end_date);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PanguSelectDateView, defStyleAttr, 0);//名称title = typedArray.getString(R.styleable.PanguSelectDateView_pgsdate_title);//开始时间的提示hintStart = typedArray.getString(R.styleable.PanguSelectDateView_pgsdate_hint_start);//结束时间的提示hintEnd = typedArray.getString(R.styleable.PanguSelectDateView_pgsdate_hint_end);//是否可用enable = typedArray.getBoolean(R.styleable.PanguSelectDateView_pgsdate_enable, true);//必选must = typedArray.getBoolean(R.styleable.PanguSelectDateView_pgsdate_must, false);//显示日期样式//0,年; 1,年月日; 2,年月日时分;3,月日;4,时分;5年月日时分秒csdate_select_mode = typedArray.getInt(R.styleable.PanguSelectDateView_pgsdate_select_mode, 1);//1,显示一个日期 ; 2,显示两个日期csdate_show_mode = typedArray.getInt(R.styleable.PanguSelectDateView_pgsdate_show_mode, 2);//是否显示标题showTitle = typedArray.getInt(R.styleable.PanguSelectDateView_pgsdate_show_title, 0);typedArray.recycle();init();}public void init() {FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);this.setLayoutParams(params);mCsvStartDate.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {showTimePicker(0, csdate_select_mode);}});mCsvEndDate.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {showTimePicker(1, csdate_select_mode);}});setDateShowMode(csdate_show_mode);setDateSelectMode(csdate_select_mode);setIsMust(must);setHintStart(hintStart);setHintEnd(hintEnd);setTitle(title);setEnable(enable);setTitleVisibility(showTitle);}/*** 设置布局宽高** @param width* @param height*/public void setSize(int width, int height) {ViewGroup.LayoutParams layoutParams = mRoot.getLayoutParams();layoutParams.width = width;layoutParams.height = height;mRoot.setLayoutParams(layoutParams);}public void setIsMust(boolean must) {this.must = must;mCsvStartDate.setIsMust(must);}private void setHintEnd(String hintEnd) {mCsvEndDate.setHint(hintEnd);}public void setHintStart(String hintStart) {mCsvStartDate.setHint(hintStart);}/*** 是否显示标题** @param visibility {@link View#VISIBLE} {@link View#INVISIBLE} {@link View#GONE}*/public void setTitleVisibility(int visibility) {if (mCsvStartDate != null) {mCsvStartDate.setTitleVisibility(visibility);}if (mCsvEndDate != null) {mCsvEndDate.setTitleVisibility(visibility);}}/*** 日期显示形式** @param mode 1,显示一个日期 ; 2,显示两个日期*/public void setDateShowMode(int mode) {this.csdate_show_mode = mode;mIvArrow.setVisibility(mode == 1 ? GONE : VISIBLE);mCsvEndDate.setVisibility(mode == 1 ? GONE : VISIBLE);}/*** 日期选择形式** @param mode 0,年; 1,年月日; 2,年月日时分;3,月日;4,时分;5年月日时分秒*/public void setDateSelectMode(int mode) {csdate_select_mode = mode;switch (csdate_select_mode) {case 0:transFormat = "yyyy";break;case 1:transFormat = "yyyy-MM-dd";break;case 2:transFormat = "yyyy-MM-dd HH:mm";break;case 3:transFormat = "MM-dd";break;case 4:transFormat = "HH:mm";break;case 5:transFormat = "yyyy-MM-dd HH:mm:ss";break;}}/*** 日期选择形式** @return {@link #setDateSelectMode(int)}*/public int getDateSelectMode() {return csdate_select_mode;}/*** 获取时间转换格式** @return 时间转换格式 {@link #setDateSelectMode(int)}*/public String getDateTransFormat() {return transFormat;}//设置搜索条件名称和输入提示public void setData(String name, String keyStart, String keyEnd) {mCsvStartDate.setTitle(name);mCsvStartDate.setSelectText("", keyStart);mCsvEndDate.setSelectText("", keyEnd);this.keyStart = keyStart;this.keyEnd = keyEnd;}private String transFormat = "yyyy-MM-dd";/*** 显示时间选择** @param type 0,开始时间; 1,结束时间*/private void showTimePicker(int type, int csdate_select_mode) {PopSelectDate timePicker = new PopSelectDate(getContext());timePicker.setDateSelectMode(csdate_select_mode);//回显时间滚轮时间timePicker.setCurrentDate(type == 0 ? getStartTime() : getEndTime(), transFormat);timePicker.setOnClickSureListener(view -> {String selctTime = timePicker.getSelectDate(transFormat);if (onDateSureListener != null) {//true的话代表自己处理long dateTimeMillis = DateUtil.getDateTimeMillis(selctTime, transFormat);boolean sureClick = onDateSureListener.onSureClick(type, type == 0 ? mCsvStartDate : mCsvEndDate, selctTime, dateTimeMillis);if (sureClick) {return;}}if (type == 0) {// 开始时间setStartTime(selctTime);} else {// 结束时间setEndTime(selctTime);}//timePicker.dismiss();});timePicker.showAtCenter();}/*** 设置开始时间** @param t*/public void setStartTime(String t) {if (mCsvStartDate != null)mCsvStartDate.setSelectText("", t);}/*** 设置结束时间** @param t*/public void setEndTime(String t) {if (mCsvEndDate != null)mCsvEndDate.setSelectText("", t);}/*** @return*/public String getYear() {if (csdate_select_mode == 0 || csdate_select_mode == 1 || csdate_select_mode == 2 || csdate_select_mode == 5) {String startTime = getStartTime();if (!TextUtils.isEmpty(startTime)) {return startTime.substring(0, 4);}}return "";}/*** 获取开始时间** @return*/public String getStartTime() {String start = mCsvStartDate.getValue();if (TextUtils.isEmpty(start)) {start = "";}return start;}/*** 获取结束时间** @return*/public String getEndTime() {String end = mCsvEndDate.getValue();if (TextUtils.isEmpty(end)) {end = "";}return end;}/*** 获取开始时间** @return*/public long getStartTimeMillis() {String start = mCsvStartDate.getValue();if (TextUtils.isEmpty(start)) {start = "";}String originFormat = "";switch (csdate_select_mode) {case 0:originFormat = "yyyy";break;case 1:originFormat = "yyyy-MM-dd";break;case 2:originFormat = "yyyy-MM-dd HH:mm";break;case 3:originFormat = "MM-dd";break;case 4:originFormat = "HH:mm";break;case 5:originFormat = "yyyy-MM-dd HH:mm:ss";break;}return DateUtil.getDateTimeMillis(start, originFormat);}/*** 获取结束时间** @return*/public long getEndTimeMillis() {String end = mCsvEndDate.getValue();if (TextUtils.isEmpty(end)) {end = "";}String originFormat = "";switch (csdate_select_mode) {case 0:originFormat = "yyyy";break;case 1:originFormat = "yyyy-MM-dd";break;case 2:originFormat = "yyyy-MM-dd HH:mm";break;case 3:originFormat = "MM-dd";break;case 4:originFormat = "HH:mm";break;case 5:originFormat = "yyyy-MM-dd HH:mm:ss";break;}return DateUtil.getDateTimeMillis(end, originFormat);}/*** 重置*/public void reset() {mCsvStartDate.setSelectText("", "");mCsvEndDate.setSelectText("", "");}public void setTitle(String title) {if (mCsvStartDate != null) {mCsvStartDate.setTitle(title);}}public void setEnable(boolean enable) {this.enable = enable;mCsvStartDate.setEnable(enable);mCsvEndDate.setEnable(enable);}private OnDateSureListener onDateSureListener;//确定public void setOnDateSureListener(OnDateSureListener onDateSureListener) {this.onDateSureListener = onDateSureListener;}//日期选中点击确定public interface OnDateSureListener {/*** 确定** @param type 0,开始时间; 1,结束时间* @param view 选择控件* @param currentSelectDate 当前选择的日期* @param currentSelectDateMillis 当前选择的日期时间戳* @return*/boolean onSureClick(int type, PanguSelectView view, String currentSelectDate, long currentSelectDateMillis);}
}
5, 获取地址
demo地址,点击查看github
欢迎您扫码安装体验demo