如何禁用日历中的未来日期? [复制]
Posted
技术标签:
【中文标题】如何禁用日历中的未来日期? [复制]【英文标题】:How to disable future dates in Calendar? [duplicate] 【发布时间】:2018-06-28 09:12:46 【问题描述】:我正在使用自定义日历来显示。但是如何禁用在日历弹出中不显示未来日期?
这是我的代码。在这段代码中,我使用自定义日历来显示。但是我不知道在哪里禁用,因为不显示未来的日期。
public class CalendarNumbersView extends View
public static final int MAX_WEEKS_IN_MONTH = 7;
private float MAX_SELECTION_FINGER_SHIFT_DIST = 5.0f;
private TextPaint paint;
private int cellPadding;
private int textColor;
private int inactiveTextColor;
private int selectionTextColor;
private int cellBackgroundColor;
private int cellSelectionBackgroundColor;
private int dayNamesTextColor;
private int dayNamesBackgroundColor;
private boolean showDayNames = true;
private Locale locale = Locale.getDefault();
private Calendar selectedDate;
private Calendar shownMonth;
private DateSelectionListener listener = null;
//temporary and cache values
private int _cachedCellSideWidth = 0;
private int _cachedCellSideHeight = 0;
private Calendar _calendar = Calendar.getInstance();
private Rect _rect = new Rect();
private float _textHeight = 0;
private float _x;
private float _y;
private Typeface _boldTypeface;
private Typeface _defaultTypeface;
public interface DateSelectionListener
void onDateSelected(Calendar selectedDate);
public static class CalendarDayCellCoord
public int col;
public int row;
public CalendarDayCellCoord(int col, int row)
this.col = col;
this.row = row;
public CalendarNumbersView(Context context)
super(context);
init(null);
public CalendarNumbersView(Context context, AttributeSet attrs)
super(context, attrs);
init(attrs);
public CalendarNumbersView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
init(attrs);
private void init(AttributeSet attrs)
paint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
paint.setTextSize(getResources().getDimensionPixelSize(R.dimen.calendar_default_text_size));
textColor = getResources().getColor(R.color.calendar_default_text_color);
//changed by adding color in inactive text.(previous month days)
inactiveTextColor = Color.parseColor("#FFFFFFFF");
selectionTextColor = getResources().getColor(R.color.calendar_default_selection_text_color);
cellPadding = getResources().getDimensionPixelSize(R.dimen.calendar_default_cell_padding);
cellBackgroundColor = getResources().getColor(R.color.calendar_default_cell_background_color);
//cellSelectionBackgroundColor = getResources().getColor(R.color.calendar_default_cell_selection_background_color);
dayNamesTextColor = getResources().getColor(R.color.calendar_default_day_names_cell_text_color);
dayNamesBackgroundColor = getResources().getColor(R.color.calendar_default_day_names_cell_background_color);
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.CalendarNumbersView);
if (ta != null)
paint.setTextSize(ta.getDimensionPixelSize(R.styleable.CalendarNumbersView_fontSize, (int) paint.getTextSize()));
textColor = ta.getColor(R.styleable.CalendarNumbersView_textColor, textColor);
inactiveTextColor = ta.getColor(R.styleable.CalendarNumbersView_inactiveTextColor, inactiveTextColor);
selectionTextColor = ta.getColor(R.styleable.CalendarNumbersView_selectionTextColor, selectionTextColor);
cellPadding = ta.getDimensionPixelSize(R.styleable.CalendarNumbersView_cellPadding, cellPadding);
cellBackgroundColor = ta.getColor(R.styleable.CalendarNumbersView_cellBackgroundColor, cellBackgroundColor);
cellSelectionBackgroundColor = ta.getColor(R.styleable.CalendarNumbersView_cellSelectionBackgroundColor, cellSelectionBackgroundColor);
dayNamesTextColor = ta.getColor(R.styleable.CalendarNumbersView_cellDayNamesCellTextColor, dayNamesTextColor);
dayNamesBackgroundColor = ta.getColor(R.styleable.CalendarNumbersView_cellDayNamesCellBackgroundColor, dayNamesBackgroundColor);
selectedDate = Calendar.getInstance();
shownMonth = (Calendar) selectedDate.clone();
public int calculateQuadCellSideWidth()
Rect bounds = new Rect();
String str = "WW";//widest possible cell string
paint.getTextBounds(str, 0, str.length(), bounds);
int maxWidth = bounds.width();
int maxHeight = bounds.height();
_textHeight = bounds.height();
return Math.max(maxWidth, maxHeight) + cellPadding * 2;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
int quadCellSideWidth = calculateQuadCellSideWidth();
int calculatedWidth = quadCellSideWidth * shownMonth.getActualMaximum(Calendar.DAY_OF_WEEK) + getPaddingLeft() + getPaddingRight();
int calculatedHeight = quadCellSideWidth * MAX_WEEKS_IN_MONTH + getPaddingTop() + getPaddingBottom();
if (showDayNames)
calculatedHeight += quadCellSideWidth;
int minimumWidth = Math.max(getSuggestedMinimumWidth(), calculatedWidth);
int minimumHeight = Math.max(getSuggestedMinimumHeight(), calculatedHeight);
int width = chooseSize(minimumWidth, widthMeasureSpec);
int height = chooseSize(minimumHeight, heightMeasureSpec);
setMeasuredDimension(width, height);
public int chooseSize(int size, int measureSpec)
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode)
case MeasureSpec.UNSPECIFIED:
case MeasureSpec.AT_MOST:
result = size;
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
return result;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
_cachedCellSideWidth = (w - getPaddingRight() - getPaddingLeft()) / shownMonth.getActualMaximum(Calendar.DAY_OF_WEEK);
_cachedCellSideHeight = (h - getPaddingTop() - getPaddingBottom()) / MAX_WEEKS_IN_MONTH;
super.onSizeChanged(w, h, oldw, oldh);
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
if (showDayNames)
setCalendarToFirstVisibleDay(_calendar);
DateFormatSymbols symbols = new DateFormatSymbols(locale);
for (int col = 0; col < _calendar.getActualMaximum(Calendar.DAY_OF_WEEK); col++)
String str = _calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, locale);
String name = str.substring(0, str.length() - 1);
drawCell(canvas, -1, col, dayNamesTextColor, dayNamesBackgroundColor, name, true);
_calendar.add(Calendar.DAY_OF_MONTH, 1);
setCalendarToFirstVisibleDay(_calendar);
for (int row = 0; row < MAX_WEEKS_IN_MONTH; row++)
for (int col = 0; col < _calendar.getActualMaximum(Calendar.DAY_OF_WEEK); col++)
int textColor;
int backgroundColor;
if (_calendar.get(Calendar.DAY_OF_YEAR) == selectedDate.get(Calendar.DAY_OF_YEAR) &&
_calendar.get(Calendar.YEAR) == selectedDate.get(Calendar.YEAR))
textColor = selectionTextColor;
backgroundColor = cellSelectionBackgroundColor;
else
if (_calendar.get(Calendar.MONTH) == shownMonth.get(Calendar.MONTH))
textColor = this.textColor;
else
textColor = inactiveTextColor;
backgroundColor = cellBackgroundColor;
int day = _calendar.get(Calendar.DAY_OF_MONTH);
String str = Integer.toString(day);
drawCell(canvas, row, col, textColor, backgroundColor, str, false);
_calendar.add(Calendar.DAY_OF_MONTH, 1);
private void drawCell(Canvas canvas, int row, int col, int textColor, int backgroundColor, String str, boolean bold)
getRectForCell(col, row, _rect);
paint.setColor(backgroundColor);
_rect.inset(cellPadding, cellPadding);
canvas.drawRect(_rect, paint);
_rect.inset(-cellPadding, -cellPadding);
paint.setColor(textColor);
if (bold)
if (_boldTypeface == null)
_boldTypeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL);//su,mo,tu,wed
paint.setTypeface(_boldTypeface);
else
if (_defaultTypeface == null)
_defaultTypeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL);
paint.setTypeface(_defaultTypeface);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(str,
_rect.left + _cachedCellSideWidth / 2f,
_rect.top + _cachedCellSideHeight / 2f + _textHeight / 2f - paint.getFontMetrics().descent / 2,
paint);
private void setCalendarToFirstVisibleDay(Calendar calendar)
calendar.setTime(shownMonth.getTime());
calendar.set(Calendar.DAY_OF_MONTH, 1);
int firstDayInWeek = calendar.getFirstDayOfWeek();
int firstDayOfWeekOfCurrentMonth = calendar.get(Calendar.DAY_OF_WEEK);
int shift;
if (firstDayInWeek > firstDayOfWeekOfCurrentMonth)
shift = -(firstDayOfWeekOfCurrentMonth + calendar.getActualMaximum(Calendar.DAY_OF_WEEK) - firstDayInWeek);
else
shift = -(firstDayOfWeekOfCurrentMonth - firstDayInWeek);
calendar.add(Calendar.DAY_OF_MONTH, shift);
private void getRectForCell(int col, int row, Rect outRect)
if (showDayNames)
row++;
outRect.set(getPaddingLeft() + col * _cachedCellSideWidth,
getPaddingTop() + row * _cachedCellSideHeight,
getPaddingLeft() + col * _cachedCellSideWidth + _cachedCellSideWidth,
getPaddingTop() + row * _cachedCellSideHeight + _cachedCellSideHeight);
private CalendarDayCellCoord getCellForCoords(float x, float y)
if (x < getPaddingLeft() ||
x >= getWidth() - getPaddingRight() ||
y < getPaddingTop() ||
y >= getHeight() - getPaddingBottom())
return null;
CalendarDayCellCoord coord = new CalendarDayCellCoord(
(int) (x - getPaddingLeft()) / _cachedCellSideWidth,
(int) (y - getPaddingTop()) / _cachedCellSideHeight
);
if (showDayNames)
coord.row--;
if (coord.row < 0)
return null;
return coord;
@Override
public boolean onTouchEvent(MotionEvent event)
switch (event.getAction() & MotionEvent.ACTION_MASK)
case MotionEvent.ACTION_DOWN:
_x = event.getX();
_y = event.getY();
return true;
case MotionEvent.ACTION_UP:
float x = event.getX();
float y = event.getY();
if (Math.sqrt(Math.pow(x - _x, 2) + Math.pow(y - _y, 2)) <= MAX_SELECTION_FINGER_SHIFT_DIST)
selectDayAt(x, y);
return true;
default:
return super.onTouchEvent(event);
private void selectDayAt(float x, float y)
CalendarDayCellCoord cellCoords = getCellForCoords(x, y);
if (cellCoords == null)
return;
setCalendarToFirstVisibleDay(_calendar);
_calendar.add(Calendar.DAY_OF_YEAR, cellCoords.col);
_calendar.add(Calendar.WEEK_OF_MONTH, cellCoords.row);
selectedDate.setTime(_calendar.getTime());
if (listener != null)
listener.onDateSelected(selectedDate);
invalidate();
public int getCellBackgroundColor()
return cellBackgroundColor;
public void setCellBackgroundColor(int cellBackgroundColor)
this.cellBackgroundColor = cellBackgroundColor;
invalidate();
public int getCellPadding()
return cellPadding;
public void setCellPadding(int cellPadding)
this.cellPadding = cellPadding;
invalidate();
public int getCellSelectionBackgroundColor()
return cellSelectionBackgroundColor;
public void setCellSelectionBackgroundColor(int cellSelectionBackgroundColor)
this.cellSelectionBackgroundColor = cellSelectionBackgroundColor;
invalidate();
public int getInactiveTextColor()
return inactiveTextColor;
public void setInactiveTextColor(int inactiveTextColor)
this.inactiveTextColor = inactiveTextColor;
invalidate();
public DateSelectionListener getListener()
return listener;
public void setListener(DateSelectionListener listener)
this.listener = listener;
public Calendar getSelectedDate()
return selectedDate;
public void setSelectedDate(Calendar selectedDate)
this.selectedDate = selectedDate;
invalidate();
public int getSelectionTextColor()
return selectionTextColor;
public void setSelectionTextColor(int selectionTextColor)
this.selectionTextColor = selectionTextColor;
invalidate();
public int getTextColor()
return textColor;
public void setTextColor(int textColor)
this.textColor = textColor;
invalidate();
public Calendar getShownMonth()
return shownMonth;
public void setShownMonth(Calendar shownMonth)
this.shownMonth = shownMonth;
invalidate();
public boolean isShowDayNames()
return showDayNames;
public void setShowDayNames(boolean showDayNames)
this.showDayNames = showDayNames;
invalidate();
public Locale getLocale()
return locale;
public void setLocale(Locale locale)
this.locale = locale;
invalidate();
public int getDayNamesBackgroundColor()
return dayNamesBackgroundColor;
public void setDayNamesBackgroundColor(int dayNamesBackgroundColor)
this.dayNamesBackgroundColor = dayNamesBackgroundColor;
invalidate();
public int getDayNamesTextColor()
return dayNamesTextColor;
public void setDayNamesTextColor(int dayNamesTextColor)
this.dayNamesTextColor = dayNamesTextColor;
invalidate();
日历选择器视图:
public class CalendarPickerView extends FrameLayout
private CalendarNumbersView calendar;
private TextView tvCalendarCaption;
private ImageView ivPrevMonth;
private ImageView ivNextMonth;
public CalendarPickerView(Context context)
super(context);
init();
public CalendarPickerView(Context context, AttributeSet attrs)
super(context, attrs);
init();
public CalendarPickerView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
init();
private void init()
LayoutInflater.from(getContext()).inflate(R.layout.view_date_time_picker, this);
tvCalendarCaption = (TextView) findViewById(R.id.tvCalendarCaption);
calendar = (CalendarNumbersView) findViewById(R.id.calendar);
ivPrevMonth = (ImageView) findViewById(R.id.ivPrevMonth);
ivNextMonth = (ImageView) findViewById(R.id.ivNextMonth);
ivPrevMonth.setOnClickListener(onPrevMonthClickListener);
ivNextMonth.setOnClickListener(onNextMonthClickListener);
updateCaption();
public void setListener(CalendarNumbersView.DateSelectionListener listener)
calendar.setListener(listener);
public CalendarNumbersView.DateSelectionListener getListener()
return calendar.getListener();
private void updateCaption()
SimpleDateFormat format = new SimpleDateFormat("MMMM yyyy", Locale.getDefault());
tvCalendarCaption.setText(format.format(calendar.getShownMonth().getTime()).toUpperCase());
public CalendarNumbersView getCalendar()
return calendar;
private OnClickListener onPrevMonthClickListener = new OnClickListener()
@Override
public void onClick(View v)
Calendar prevMonth = calendar.getShownMonth();
prevMonth.add(Calendar.MONTH, -1);
calendar.setShownMonth(prevMonth);
updateCaption();
;
private OnClickListener onNextMonthClickListener = new OnClickListener()
@Override
public void onClick(View v)
Calendar nextMonth = calendar.getShownMonth();
nextMonth.add(Calendar.MONTH, 1);
calendar.setShownMonth(nextMonth);
updateCaption();
;
不显示未来日期,我不知道在哪里禁用。
在 MainActivity 中,
在按钮点击中,我只是展示了这个 CalendarPickerView,
CalendarPickerView calendarView = new CalendarPickerView(SummaryActivities.this);
calendarView.setListener(dateSelectionListener);
calendarPopup.setContentView(calendarView);
calendarPopup.show();
private CalendarNumbersView.DateSelectionListener dateSelectionListener = new CalendarNumbersView.DateSelectionListener()
@Override
public void onDateSelected(Calendar selectedDate)
if (calendarPopup.isShowing())
calendarPopup.dismiss();
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
dateTxt.setText(formatter.format(selectedDate.getTime()));
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(selectedDate.getTime());
setSummaryRequest(AppUtils.getRequestMsisdn(), formattedDate);
;
【问题讨论】:
有个方法叫.setMaxDate(new Date()) 看看吧 不能重复!!我从未在代码中使用过 DatePicker。 mDatePicker.getDatePicker().setMaxDate(System.currentTimeMillis());在我的代码中添加这一行!!如果你可以的话!!然后说它是如何重复的 github.com/square/android-times-square/issues/409 这对你来说可能是地狱 【参考方案1】:试试这个How set maximum date in datepicker dialog in android?
还有这个How to Disable future dates in Android date picker
【讨论】:
我没有使用 DatePicker。这是自定义日历。【参考方案2】:你可以做到!在customCalendarView.onDraw();
方法中。如果时间是未来就不要画时间!
【讨论】:
你能告诉我需要在哪一行更正吗?以上是关于如何禁用日历中的未来日期? [复制]的主要内容,如果未能解决你的问题,请参考以下文章