FileDocCategorySizeDatePackage
MonthView.javaAPI DocAndroid 5.1 API29410Thu Mar 12 22:22:50 GMT 2015com.android.datetimepicker.date

MonthView

public abstract class MonthView extends android.view.View
A calendar-like view displaying a specified month and the appropriate selectable day numbers within the specified month.

Fields Summary
private static final String
TAG
public static final String
VIEW_PARAMS_HEIGHT
This sets the height of this week in pixels
public static final String
VIEW_PARAMS_MONTH
This specifies the position (or weeks since the epoch) of this week, calculated using {@link Utils#getWeeksSinceEpochFromJulianDay}
public static final String
VIEW_PARAMS_YEAR
This specifies the position (or weeks since the epoch) of this week, calculated using {@link Utils#getWeeksSinceEpochFromJulianDay}
public static final String
VIEW_PARAMS_SELECTED_DAY
This sets one of the days in this view as selected {@link Time#SUNDAY} through {@link Time#SATURDAY}.
public static final String
VIEW_PARAMS_WEEK_START
Which day the week should start on. {@link Time#SUNDAY} through {@link Time#SATURDAY}.
public static final String
VIEW_PARAMS_NUM_DAYS
How many days to display at a time. Days will be displayed starting with {@link #mWeekStart}.
public static final String
VIEW_PARAMS_FOCUS_MONTH
Which month is currently in focus, as defined by {@link Time#month} [0-11].
public static final String
VIEW_PARAMS_SHOW_WK_NUM
If this month should display week numbers. false if 0, true otherwise.
protected static int
DEFAULT_HEIGHT
protected static int
MIN_HEIGHT
protected static final int
DEFAULT_SELECTED_DAY
protected static final int
DEFAULT_WEEK_START
protected static final int
DEFAULT_NUM_DAYS
protected static final int
DEFAULT_SHOW_WK_NUM
protected static final int
DEFAULT_FOCUS_MONTH
protected static final int
DEFAULT_NUM_ROWS
protected static final int
MAX_NUM_ROWS
private static final int
SELECTED_CIRCLE_ALPHA
protected static int
DAY_SEPARATOR_WIDTH
protected static int
MINI_DAY_NUMBER_TEXT_SIZE
protected static int
MONTH_LABEL_TEXT_SIZE
protected static int
MONTH_DAY_LABEL_TEXT_SIZE
protected static int
MONTH_HEADER_SIZE
protected static int
DAY_SELECTED_CIRCLE_SIZE
protected static float
mScale
protected DatePickerController
mController
protected int
mEdgePadding
private String
mDayOfWeekTypeface
private String
mMonthTitleTypeface
protected android.graphics.Paint
mMonthNumPaint
protected android.graphics.Paint
mMonthTitlePaint
protected android.graphics.Paint
mMonthTitleBGPaint
protected android.graphics.Paint
mSelectedCirclePaint
protected android.graphics.Paint
mMonthDayLabelPaint
private final Formatter
mFormatter
private final StringBuilder
mStringBuilder
protected int
mFirstJulianDay
protected int
mFirstMonth
protected int
mLastMonth
protected int
mMonth
protected int
mYear
protected int
mWidth
protected int
mRowHeight
protected boolean
mHasToday
protected int
mSelectedDay
protected int
mToday
protected int
mWeekStart
protected int
mNumDays
protected int
mNumCells
protected int
mSelectedLeft
protected int
mSelectedRight
private final Calendar
mCalendar
protected final Calendar
mDayLabelCalendar
private final MonthViewTouchHelper
mTouchHelper
protected int
mNumRows
protected OnDayClickListener
mOnDayClickListener
private boolean
mLockAccessibilityDelegate
protected int
mDayTextColor
protected int
mTodayNumberColor
protected int
mDisabledDayTextColor
protected int
mMonthTitleColor
protected int
mMonthTitleBGColor
private int
mDayOfWeekStart
Constructors Summary
public MonthView(android.content.Context context)


       
        this(context, null);
    
public MonthView(android.content.Context context, android.util.AttributeSet attr)

        super(context, attr);
        Resources res = context.getResources();

        mDayLabelCalendar = Calendar.getInstance();
        mCalendar = Calendar.getInstance();

        mDayOfWeekTypeface = res.getString(R.string.day_of_week_label_typeface);
        mMonthTitleTypeface = res.getString(R.string.sans_serif);

        mDayTextColor = res.getColor(R.color.date_picker_text_normal);
        mTodayNumberColor = res.getColor(R.color.blue);
        mDisabledDayTextColor = res.getColor(R.color.date_picker_text_disabled);
        mMonthTitleColor = res.getColor(R.color.white);
        mMonthTitleBGColor = res.getColor(R.color.circle_background);

        mStringBuilder = new StringBuilder(50);
        mFormatter = new Formatter(mStringBuilder, Locale.getDefault());

        MINI_DAY_NUMBER_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.day_number_size);
        MONTH_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.month_label_size);
        MONTH_DAY_LABEL_TEXT_SIZE = res.getDimensionPixelSize(R.dimen.month_day_label_text_size);
        MONTH_HEADER_SIZE = res.getDimensionPixelOffset(R.dimen.month_list_item_header_height);
        DAY_SELECTED_CIRCLE_SIZE = res
                .getDimensionPixelSize(R.dimen.day_number_select_circle_radius);

        mRowHeight = (res.getDimensionPixelOffset(R.dimen.date_picker_view_animator_height)
                - getMonthHeaderSize()) / MAX_NUM_ROWS;

        // Set up accessibility components.
        mTouchHelper = getMonthViewTouchHelper();
        ViewCompat.setAccessibilityDelegate(this, mTouchHelper);
        ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
        mLockAccessibilityDelegate = true;

        // Sets up any standard paints that will be used
        initView();
    
Methods Summary
private intcalculateNumRows()

        int offset = findDayOffset();
        int dividend = (offset + mNumCells) / mNumDays;
        int remainder = (offset + mNumCells) % mNumDays;
        return (dividend + (remainder > 0 ? 1 : 0));
    
public voidclearAccessibilityFocus()
Clears accessibility focus within the view. No-op if the view does not contain accessibility focus.

        mTouchHelper.clearFocusedVirtualView();
    
public booleandispatchHoverEvent(android.view.MotionEvent event)

        // First right-of-refusal goes the touch exploration helper.
        if (mTouchHelper.dispatchHoverEvent(event)) {
            return true;
        }
        return super.dispatchHoverEvent(event);
    
public abstract voiddrawMonthDay(android.graphics.Canvas canvas, int year, int month, int day, int x, int y, int startX, int stopX, int startY, int stopY)
This method should draw the month day. Implemented by sub-classes to allow customization.

param
canvas The canvas to draw on
param
year The year of this month day
param
month The month of this month day
param
day The day number of this month day
param
x The default x position to draw the day number
param
y The default y position to draw the day number
param
startX The left boundary of the day number rect
param
stopX The right boundary of the day number rect
param
startY The top boundary of the day number rect
param
stopY The bottom boundary of the day number rect

protected voiddrawMonthDayLabels(android.graphics.Canvas canvas)

        int y = getMonthHeaderSize() - (MONTH_DAY_LABEL_TEXT_SIZE / 2);
        int dayWidthHalf = (mWidth - mEdgePadding * 2) / (mNumDays * 2);

        for (int i = 0; i < mNumDays; i++) {
            int calendarDay = (i + mWeekStart) % mNumDays;
            int x = (2 * i + 1) * dayWidthHalf + mEdgePadding;
            mDayLabelCalendar.set(Calendar.DAY_OF_WEEK, calendarDay);
            canvas.drawText(mDayLabelCalendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT,
                    Locale.getDefault()).toUpperCase(Locale.getDefault()), x, y,
                    mMonthDayLabelPaint);
        }
    
protected voiddrawMonthNums(android.graphics.Canvas canvas)
Draws the week and month day numbers for this week. Override this method if you need different placement.

param
canvas The canvas to draw on

        int y = (((mRowHeight + MINI_DAY_NUMBER_TEXT_SIZE) / 2) - DAY_SEPARATOR_WIDTH)
                + getMonthHeaderSize();
        final float dayWidthHalf = (mWidth - mEdgePadding * 2) / (mNumDays * 2.0f);
        int j = findDayOffset();
        for (int dayNumber = 1; dayNumber <= mNumCells; dayNumber++) {
            final int x = (int)((2 * j + 1) * dayWidthHalf + mEdgePadding);

            int yRelativeToDay = (mRowHeight + MINI_DAY_NUMBER_TEXT_SIZE) / 2 - DAY_SEPARATOR_WIDTH;

            final int startX = (int)(x - dayWidthHalf);
            final int stopX = (int)(x + dayWidthHalf);
            final int startY = (int)(y - yRelativeToDay);
            final int stopY = (int)(startY + mRowHeight);

            drawMonthDay(canvas, mYear, mMonth, dayNumber, x, y, startX, stopX, startY, stopY);

            j++;
            if (j == mNumDays) {
                j = 0;
                y += mRowHeight;
            }
        }
    
protected voiddrawMonthTitle(android.graphics.Canvas canvas)

        int x = (mWidth + 2 * mEdgePadding) / 2;
        int y = (getMonthHeaderSize() - MONTH_DAY_LABEL_TEXT_SIZE) / 2 + (MONTH_LABEL_TEXT_SIZE / 3);
        canvas.drawText(getMonthAndYearString(), x, y, mMonthTitlePaint);
    
protected intfindDayOffset()

        return (mDayOfWeekStart < mWeekStart ? (mDayOfWeekStart + mNumDays) : mDayOfWeekStart)
                - mWeekStart;
    
public com.android.datetimepicker.date.MonthAdapter.CalendarDaygetAccessibilityFocus()

return
The date that has accessibility focus, or {@code null} if no date has focus

        final int day = mTouchHelper.getFocusedVirtualView();
        if (day >= 0) {
            return new CalendarDay(mYear, mMonth, day);
        }
        return null;
    
public intgetDayFromLocation(float x, float y)
Calculates the day that the given x position is in, accounting for week number. Returns the day or -1 if the position wasn't in a day.

param
x The x position of the touch event
return
The day number, or -1 if the position wasn't in a day

        final int day = getInternalDayFromLocation(x, y);
        if (day < 1 || day > mNumCells) {
            return -1;
        }
        return day;
    
protected intgetInternalDayFromLocation(float x, float y)
Calculates the day that the given x position is in, accounting for week number.

param
x The x position of the touch event
return
The day number

        int dayStart = mEdgePadding;
        if (x < dayStart || x > mWidth - mEdgePadding) {
            return -1;
        }
        // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
        int row = (int) (y - getMonthHeaderSize()) / mRowHeight;
        int column = (int) ((x - dayStart) * mNumDays / (mWidth - dayStart - mEdgePadding));

        int day = column - findDayOffset() + 1;
        day += row * mNumDays;
        return day;
    
public intgetMonth()

        return mMonth;
    
private java.lang.StringgetMonthAndYearString()

        int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR
                | DateUtils.FORMAT_NO_MONTH_DAY;
        mStringBuilder.setLength(0);
        long millis = mCalendar.getTimeInMillis();
        return DateUtils.formatDateRange(getContext(), mFormatter, millis, millis, flags,
                Time.getCurrentTimezone()).toString();
    
protected intgetMonthHeaderSize()
A wrapper to the MonthHeaderSize to allow override it in children

        return MONTH_HEADER_SIZE;
    
protected com.android.datetimepicker.date.MonthView$MonthViewTouchHelpergetMonthViewTouchHelper()

        return new MonthViewTouchHelper(this);
    
public intgetYear()

        return mYear;
    
protected voidinitView()
Sets up the text and style properties for painting. Override this if you want to use a different paint.

        mMonthTitlePaint = new Paint();
        mMonthTitlePaint.setFakeBoldText(true);
        mMonthTitlePaint.setAntiAlias(true);
        mMonthTitlePaint.setTextSize(MONTH_LABEL_TEXT_SIZE);
        mMonthTitlePaint.setTypeface(Typeface.create(mMonthTitleTypeface, Typeface.BOLD));
        mMonthTitlePaint.setColor(mDayTextColor);
        mMonthTitlePaint.setTextAlign(Align.CENTER);
        mMonthTitlePaint.setStyle(Style.FILL);

        mMonthTitleBGPaint = new Paint();
        mMonthTitleBGPaint.setFakeBoldText(true);
        mMonthTitleBGPaint.setAntiAlias(true);
        mMonthTitleBGPaint.setColor(mMonthTitleBGColor);
        mMonthTitleBGPaint.setTextAlign(Align.CENTER);
        mMonthTitleBGPaint.setStyle(Style.FILL);

        mSelectedCirclePaint = new Paint();
        mSelectedCirclePaint.setFakeBoldText(true);
        mSelectedCirclePaint.setAntiAlias(true);
        mSelectedCirclePaint.setColor(mTodayNumberColor);
        mSelectedCirclePaint.setTextAlign(Align.CENTER);
        mSelectedCirclePaint.setStyle(Style.FILL);
        mSelectedCirclePaint.setAlpha(SELECTED_CIRCLE_ALPHA);

        mMonthDayLabelPaint = new Paint();
        mMonthDayLabelPaint.setAntiAlias(true);
        mMonthDayLabelPaint.setTextSize(MONTH_DAY_LABEL_TEXT_SIZE);
        mMonthDayLabelPaint.setColor(mDayTextColor);
        mMonthDayLabelPaint.setTypeface(Typeface.create(mDayOfWeekTypeface, Typeface.NORMAL));
        mMonthDayLabelPaint.setStyle(Style.FILL);
        mMonthDayLabelPaint.setTextAlign(Align.CENTER);
        mMonthDayLabelPaint.setFakeBoldText(true);

        mMonthNumPaint = new Paint();
        mMonthNumPaint.setAntiAlias(true);
        mMonthNumPaint.setTextSize(MINI_DAY_NUMBER_TEXT_SIZE);
        mMonthNumPaint.setStyle(Style.FILL);
        mMonthNumPaint.setTextAlign(Align.CENTER);
        mMonthNumPaint.setFakeBoldText(false);
    
private booleanisAfterMax(int year, int month, int day)

        if (mController == null) {
            return false;
        }
        Calendar maxDate = mController.getMaxDate();
        if (maxDate == null) {
            return false;
        }

        if (year > maxDate.get(Calendar.YEAR)) {
            return true;
        } else if (year < maxDate.get(Calendar.YEAR)) {
            return false;
        }

        if (month > maxDate.get(Calendar.MONTH)) {
            return true;
        } else if (month < maxDate.get(Calendar.MONTH)) {
            return false;
        }

        if (day > maxDate.get(Calendar.DAY_OF_MONTH)) {
            return true;
        } else {
            return false;
        }
    
private booleanisBeforeMin(int year, int month, int day)

        if (mController == null) {
            return false;
        }
        Calendar minDate = mController.getMinDate();
        if (minDate == null) {
            return false;
        }

        if (year < minDate.get(Calendar.YEAR)) {
            return true;
        } else if (year > minDate.get(Calendar.YEAR)) {
            return false;
        }

        if (month < minDate.get(Calendar.MONTH)) {
            return true;
        } else if (month > minDate.get(Calendar.MONTH)) {
            return false;
        }

        if (day < minDate.get(Calendar.DAY_OF_MONTH)) {
            return true;
        } else {
            return false;
        }
    
protected booleanisOutOfRange(int year, int month, int day)

return
true if the specified year/month/day are within the range set by minDate and maxDate. If one or either have not been set, they are considered as Integer.MIN_VALUE and Integer.MAX_VALUE.

        if (isBeforeMin(year, month, day)) {
            return true;
        } else if (isAfterMax(year, month, day)) {
            return true;
        }

        return false;
    
private voidonDayClick(int day)
Called when the user clicks on a day. Handles callbacks to the {@link OnDayClickListener} if one is set.

If the day is out of the range set by minDate and/or maxDate, this is a no-op.

param
day The day that was clicked

        // If the min / max date are set, only process the click if it's a valid selection.
        if (isOutOfRange(mYear, mMonth, day)) {
            return;
        }


        if (mOnDayClickListener != null) {
            mOnDayClickListener.onDayClick(this, new CalendarDay(mYear, mMonth, day));
        }

        // This is a no-op if accessibility is turned off.
        mTouchHelper.sendEventForVirtualView(day, AccessibilityEvent.TYPE_VIEW_CLICKED);
    
protected voidonDraw(android.graphics.Canvas canvas)

        drawMonthTitle(canvas);
        drawMonthDayLabels(canvas);
        drawMonthNums(canvas);
    
protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mRowHeight * mNumRows
                + getMonthHeaderSize());
    
protected voidonSizeChanged(int w, int h, int oldw, int oldh)

        mWidth = w;

        // Invalidate cached accessibility information.
        mTouchHelper.invalidateRoot();
    
public booleanonTouchEvent(android.view.MotionEvent event)

        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                final int day = getDayFromLocation(event.getX(), event.getY());
                if (day >= 0) {
                    onDayClick(day);
                }
                break;
        }
        return true;
    
public booleanrestoreAccessibilityFocus(com.android.datetimepicker.date.MonthAdapter.CalendarDay day)
Attempts to restore accessibility focus to the specified date.

param
day The date which should receive focus
return
{@code false} if the date is not valid for this month view, or {@code true} if the date received focus

        if ((day.year != mYear) || (day.month != mMonth) || (day.day > mNumCells)) {
            return false;
        }
        mTouchHelper.setFocusedVirtualView(day.day);
        return true;
    
public voidreuse()

        mNumRows = DEFAULT_NUM_ROWS;
        requestLayout();
    
private booleansameDay(int day, android.text.format.Time today)

        return mYear == today.year &&
                mMonth == today.month &&
                day == today.monthDay;
    
public voidsetAccessibilityDelegate(AccessibilityDelegate delegate)

        // Workaround for a JB MR1 issue where accessibility delegates on
        // top-level ListView items are overwritten.
        if (!mLockAccessibilityDelegate) {
            super.setAccessibilityDelegate(delegate);
        }
    
public voidsetDatePickerController(DatePickerController controller)

        mController = controller;
    
public voidsetMonthParams(java.util.HashMap params)
Sets all the parameters for displaying this week. The only required parameter is the week number. Other parameters have a default value and will only update if a new value is included, except for focus month, which will always default to no focus month if no value is passed in. See {@link #VIEW_PARAMS_HEIGHT} for more info on parameters.

param
params A map of the new parameters, see {@link #VIEW_PARAMS_HEIGHT}


                                                                                         
         
        if (!params.containsKey(VIEW_PARAMS_MONTH) && !params.containsKey(VIEW_PARAMS_YEAR)) {
            throw new InvalidParameterException("You must specify month and year for this view");
        }
        setTag(params);
        // We keep the current value for any params not present
        if (params.containsKey(VIEW_PARAMS_HEIGHT)) {
            mRowHeight = params.get(VIEW_PARAMS_HEIGHT);
            if (mRowHeight < MIN_HEIGHT) {
                mRowHeight = MIN_HEIGHT;
            }
        }
        if (params.containsKey(VIEW_PARAMS_SELECTED_DAY)) {
            mSelectedDay = params.get(VIEW_PARAMS_SELECTED_DAY);
        }

        // Allocate space for caching the day numbers and focus values
        mMonth = params.get(VIEW_PARAMS_MONTH);
        mYear = params.get(VIEW_PARAMS_YEAR);

        // Figure out what day today is
        final Time today = new Time(Time.getCurrentTimezone());
        today.setToNow();
        mHasToday = false;
        mToday = -1;

        mCalendar.set(Calendar.MONTH, mMonth);
        mCalendar.set(Calendar.YEAR, mYear);
        mCalendar.set(Calendar.DAY_OF_MONTH, 1);
        mDayOfWeekStart = mCalendar.get(Calendar.DAY_OF_WEEK);

        if (params.containsKey(VIEW_PARAMS_WEEK_START)) {
            mWeekStart = params.get(VIEW_PARAMS_WEEK_START);
        } else {
            mWeekStart = mCalendar.getFirstDayOfWeek();
        }

        mNumCells = Utils.getDaysInMonth(mMonth, mYear);
        for (int i = 0; i < mNumCells; i++) {
            final int day = i + 1;
            if (sameDay(day, today)) {
                mHasToday = true;
                mToday = day;
            }
        }
        mNumRows = calculateNumRows();

        // Invalidate cached accessibility information.
        mTouchHelper.invalidateRoot();
    
public voidsetOnDayClickListener(com.android.datetimepicker.date.MonthView$OnDayClickListener listener)

        mOnDayClickListener = listener;
    
public voidsetSelectedDay(int day)

        mSelectedDay = day;