如何禁用日历中的未来日期? [复制]

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(); 方法中。如果时间是未来就不要画时间!

【讨论】:

你能告诉我需要在哪一行更正吗?

以上是关于如何禁用日历中的未来日期? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用角度 p 日历中的过去日期?

如何在颤动中禁用日历中的前几天?

进入当前日期后如何删除日历未来日期背景蓝色?

Datepicker 如何仅选择未来日期并禁用 JQuery 和 CSS 中的过去日期?

在 React 中禁用材料 ui 日历中的特定日期

WPF 日历禁用日期选择