@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
   mDurationStringWidth = (int) mTextPaint.measureText(mDurationString);
   mTotalDurationStringWidth = (int) mTextPaint.measureText(mTotalDurationString);
   mTextAscent = (int) mTextPaint.ascent();
   mTextDescent = (int) mTextPaint.descent();
 }
예제 #2
0
  /**
   * Returns the ascent of the text at start. This is used for scaling emoji.
   *
   * @param pos the line-relative position
   * @return the ascent of the text at start
   */
  float ascent(int pos) {
    if (mSpanned == null) {
      return mPaint.ascent();
    }

    pos += mStart;
    MetricAffectingSpan[] spans = mSpanned.getSpans(pos, pos + 1, MetricAffectingSpan.class);
    if (spans.length == 0) {
      return mPaint.ascent();
    }

    TextPaint wp = mWorkPaint;
    wp.set(mPaint);
    for (MetricAffectingSpan span : spans) {
      span.updateMeasureState(wp);
    }
    return wp.ascent();
  }
  private void drawMonth(Canvas canvas) {
    final float x = mPaddedWidth / 2f;

    // Vertically centered within the month header height.
    final float lineHeight = mMonthPaint.ascent() + mMonthPaint.descent();
    final float y = (mMonthHeight - lineHeight) / 2f;

    canvas.drawText(getTitle().toString(), x, y, mMonthPaint);
  }
예제 #4
0
  private void initIfNecessary(TextPaint tp) {
    if (jumpAnimator != null) {
      return;
    }

    shift = (int) tp.ascent() / 2;
    jumpAnimator = ValueAnimator.ofInt(0, shift, 0);
    jumpAnimator.setDuration(loopDuration).setStartDelay(delay);
    jumpAnimator.setInterpolator(new JumpInterpolator(animatedRange));
    jumpAnimator.setRepeatCount(ValueAnimator.INFINITE);
    jumpAnimator.setRepeatMode(ValueAnimator.RESTART);
    jumpAnimator.addUpdateListener(this);
    jumpAnimator.start();
  }
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    float delta = Math.max(finishedStrokeWidth, unfinishedStrokeWidth);

    finishedOuterRect.set(delta, delta, getWidth() - delta, getHeight() - delta);
    unfinishedOuterRect.set(delta, delta, getWidth() - delta, getHeight() - delta);

    //        float innerCircleRadius = (getWidth() - Math.min(finishedStrokeWidth,
    // unfinishedStrokeWidth) + Math.abs
    //                (finishedStrokeWidth - unfinishedStrokeWidth)) / 2f;
    float innerCircleRadius = (getWidth() - delta) / 2;

    //        Log.d(TAG, "width:" + getWidth());
    //        Log.d(TAG, "height:" + getHeight());
    //        Log.d(TAG, "R:" + innerCircleRadius);
    //        Log.d(TAG, "finishedStrokeWidth:" + finishedStrokeWidth);
    //        Log.d(TAG, "unfinishedStrokeWidth:" + unfinishedStrokeWidth);

    canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, innerCircleRadius, innerCirclePaint);
    canvas.drawArc(
        finishedOuterRect, getStartingDegree(), getProgressAngle(), false, finishedPaint);
    canvas.drawArc(
        unfinishedOuterRect,
        getStartingDegree() + getProgressAngle(),
        360 - getProgressAngle(),
        false,
        unfinishedPaint);

    String innerText = getInnerText();
    if (!TextUtils.isEmpty(innerText)) {
      float innerTextHeight = innerTextPaint.descent() + innerTextPaint.ascent();
      canvas.drawText(
          innerText,
          (getWidth() - innerTextPaint.measureText(innerText)) / 2,
          (getHeight() - innerTextHeight) / 2,
          innerTextPaint);
    }
  }
  private void drawDaysOfWeek(Canvas canvas) {
    final TextPaint p = mDayOfWeekPaint;
    final int headerHeight = mMonthHeight;
    final int rowHeight = mDayOfWeekHeight;
    final int colWidth = mCellWidth;

    // Text is vertically centered within the day of week height.
    final float halfLineHeight = (p.ascent() + p.descent()) / 2f;
    final int rowCenter = headerHeight + rowHeight / 2;

    for (int col = 0; col < DAYS_IN_WEEK; col++) {
      final int colCenter = colWidth * col + colWidth / 2;
      final int colCenterRtl;
      if (isLayoutRtl()) {
        colCenterRtl = mPaddedWidth - colCenter;
      } else {
        colCenterRtl = colCenter;
      }

      final int dayOfWeek = (col + mWeekStart) % DAYS_IN_WEEK;
      final String label = getDayOfWeekLabel(dayOfWeek);
      canvas.drawText(label, colCenterRtl, rowCenter - halfLineHeight, p);
    }
  }
  /**
   * Sets up the text and style properties for painting. Override this if you want to use a
   * different paint.
   */
  @Override
  protected void initView() {
    super.initView();

    if (!mInitialized) {
      Resources resources = getContext().getResources();
      mShowDetailsInMonth = Utils.getConfigBool(getContext(), R.bool.show_details_in_month);
      TEXT_SIZE_EVENT_TITLE = resources.getInteger(R.integer.text_size_event_title);
      TEXT_SIZE_MONTH_NUMBER = resources.getInteger(R.integer.text_size_month_number);
      SIDE_PADDING_MONTH_NUMBER = resources.getInteger(R.integer.month_day_number_margin);
      CONFLICT_COLOR = resources.getColor(R.color.month_dna_conflict_time_color);
      EVENT_TEXT_COLOR = resources.getColor(R.color.calendar_event_text_color);
      if (mScale != 1) {
        TOP_PADDING_MONTH_NUMBER *= mScale;
        TOP_PADDING_WEEK_NUMBER *= mScale;
        SIDE_PADDING_MONTH_NUMBER *= mScale;
        SIDE_PADDING_WEEK_NUMBER *= mScale;
        SPACING_WEEK_NUMBER *= mScale;
        TEXT_SIZE_MONTH_NUMBER *= mScale;
        TEXT_SIZE_EVENT *= mScale;
        TEXT_SIZE_EVENT_TITLE *= mScale;
        TEXT_SIZE_MORE_EVENTS *= mScale;
        TEXT_SIZE_MONTH_NAME *= mScale;
        TEXT_SIZE_WEEK_NUM *= mScale;
        DAY_SEPARATOR_OUTER_WIDTH *= mScale;
        DAY_SEPARATOR_INNER_WIDTH *= mScale;
        DAY_SEPARATOR_VERTICAL_LENGTH *= mScale;
        DAY_SEPARATOR_VERTICAL_LENGHT_PORTRAIT *= mScale;
        EVENT_X_OFFSET_LANDSCAPE *= mScale;
        EVENT_Y_OFFSET_LANDSCAPE *= mScale;
        EVENT_Y_OFFSET_PORTRAIT *= mScale;
        EVENT_SQUARE_WIDTH *= mScale;
        EVENT_SQUARE_BORDER *= mScale;
        EVENT_LINE_PADDING *= mScale;
        EVENT_BOTTOM_PADDING *= mScale;
        EVENT_RIGHT_PADDING *= mScale;
        DNA_MARGIN *= mScale;
        DNA_WIDTH *= mScale;
        DNA_ALL_DAY_HEIGHT *= mScale;
        DNA_MIN_SEGMENT_HEIGHT *= mScale;
        DNA_SIDE_PADDING *= mScale;
        DEFAULT_EDGE_SPACING *= mScale;
        DNA_ALL_DAY_WIDTH *= mScale;
        TODAY_HIGHLIGHT_WIDTH *= mScale;
      }
      if (!mShowDetailsInMonth) {
        TOP_PADDING_MONTH_NUMBER += DNA_ALL_DAY_HEIGHT + DNA_MARGIN;
      }
      mInitialized = true;
    }
    mPadding = DEFAULT_EDGE_SPACING;
    loadColors(getContext());
    // TODO modify paint properties depending on isMini

    mMonthNumPaint = new Paint();
    mMonthNumPaint.setFakeBoldText(false);
    mMonthNumPaint.setAntiAlias(true);
    mMonthNumPaint.setTextSize(TEXT_SIZE_MONTH_NUMBER);
    mMonthNumPaint.setColor(mMonthNumColor);
    mMonthNumPaint.setStyle(Style.FILL);
    mMonthNumPaint.setTextAlign(Align.RIGHT);
    mMonthNumPaint.setTypeface(Typeface.DEFAULT);

    mMonthNumAscentHeight = (int) (-mMonthNumPaint.ascent() + 0.5f);
    mMonthNumHeight = (int) (mMonthNumPaint.descent() - mMonthNumPaint.ascent() + 0.5f);

    mEventPaint = new TextPaint();
    mEventPaint.setFakeBoldText(true);
    mEventPaint.setAntiAlias(true);
    mEventPaint.setTextSize(TEXT_SIZE_EVENT_TITLE);
    mEventPaint.setColor(mMonthEventColor);

    mSolidBackgroundEventPaint = new TextPaint(mEventPaint);
    mSolidBackgroundEventPaint.setColor(EVENT_TEXT_COLOR);
    mFramedEventPaint = new TextPaint(mSolidBackgroundEventPaint);

    mDeclinedEventPaint = new TextPaint();
    mDeclinedEventPaint.setFakeBoldText(true);
    mDeclinedEventPaint.setAntiAlias(true);
    mDeclinedEventPaint.setTextSize(TEXT_SIZE_EVENT_TITLE);
    mDeclinedEventPaint.setColor(mMonthDeclinedEventColor);

    mEventAscentHeight = (int) (-mEventPaint.ascent() + 0.5f);
    mEventHeight = (int) (mEventPaint.descent() - mEventPaint.ascent() + 0.5f);

    mEventExtrasPaint = new TextPaint();
    mEventExtrasPaint.setFakeBoldText(false);
    mEventExtrasPaint.setAntiAlias(true);
    mEventExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER);
    mEventExtrasPaint.setTextSize(TEXT_SIZE_EVENT);
    mEventExtrasPaint.setColor(mMonthEventExtraColor);
    mEventExtrasPaint.setStyle(Style.FILL);
    mEventExtrasPaint.setTextAlign(Align.LEFT);
    mExtrasHeight = (int) (mEventExtrasPaint.descent() - mEventExtrasPaint.ascent() + 0.5f);
    mExtrasAscentHeight = (int) (-mEventExtrasPaint.ascent() + 0.5f);
    mExtrasDescent = (int) (mEventExtrasPaint.descent() + 0.5f);

    mEventDeclinedExtrasPaint = new TextPaint();
    mEventDeclinedExtrasPaint.setFakeBoldText(false);
    mEventDeclinedExtrasPaint.setAntiAlias(true);
    mEventDeclinedExtrasPaint.setStrokeWidth(EVENT_SQUARE_BORDER);
    mEventDeclinedExtrasPaint.setTextSize(TEXT_SIZE_EVENT);
    mEventDeclinedExtrasPaint.setColor(mMonthDeclinedExtrasColor);
    mEventDeclinedExtrasPaint.setStyle(Style.FILL);
    mEventDeclinedExtrasPaint.setTextAlign(Align.LEFT);

    mWeekNumPaint = new Paint();
    mWeekNumPaint.setFakeBoldText(false);
    mWeekNumPaint.setAntiAlias(true);
    mWeekNumPaint.setTextSize(TEXT_SIZE_WEEK_NUM);
    mWeekNumPaint.setColor(mWeekNumColor);
    mWeekNumPaint.setStyle(Style.FILL);
    mWeekNumPaint.setTextAlign(Align.RIGHT);

    mWeekNumAscentHeight = (int) (-mWeekNumPaint.ascent() + 0.5f);

    mDNAAllDayPaint = new Paint();
    mDNATimePaint = new Paint();
    mDNATimePaint.setColor(mMonthBusyBitsBusyTimeColor);
    mDNATimePaint.setStyle(Style.FILL_AND_STROKE);
    mDNATimePaint.setStrokeWidth(DNA_WIDTH);
    mDNATimePaint.setAntiAlias(false);
    mDNAAllDayPaint.setColor(mMonthBusyBitsConflictTimeColor);
    mDNAAllDayPaint.setStyle(Style.FILL_AND_STROKE);
    mDNAAllDayPaint.setStrokeWidth(DNA_ALL_DAY_WIDTH);
    mDNAAllDayPaint.setAntiAlias(false);

    mEventSquarePaint = new Paint();
    mEventSquarePaint.setStrokeWidth(EVENT_SQUARE_BORDER);
    mEventSquarePaint.setAntiAlias(false);

    if (DEBUG_LAYOUT) {
      Log.d("EXTRA", "mScale=" + mScale);
      Log.d(
          "EXTRA",
          "mMonthNumPaint ascent="
              + mMonthNumPaint.ascent()
              + " descent="
              + mMonthNumPaint.descent()
              + " int height="
              + mMonthNumHeight);
      Log.d(
          "EXTRA",
          "mEventPaint ascent="
              + mEventPaint.ascent()
              + " descent="
              + mEventPaint.descent()
              + " int height="
              + mEventHeight
              + " int ascent="
              + mEventAscentHeight);
      Log.d(
          "EXTRA",
          "mEventExtrasPaint ascent="
              + mEventExtrasPaint.ascent()
              + " descent="
              + mEventExtrasPaint.descent()
              + " int height="
              + mExtrasHeight);
      Log.d(
          "EXTRA",
          "mWeekNumPaint ascent=" + mWeekNumPaint.ascent() + " descent=" + mWeekNumPaint.descent());
    }
  }
 @Override
 protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);
   int radius = 0;
   int shadowColor = changeColorAlpha(mShadowColor, MIN_SHADOW_COLOR_ALPHA);
   long elapsed = System.currentTimeMillis() - mStartTime;
   switch (mState) {
     case StateNormal:
       shadowColor = changeColorAlpha(mShadowColor, MIN_SHADOW_COLOR_ALPHA);
       break;
     case StateTouchDown:
       ripplePaint.setAlpha(255);
       if (elapsed < ANIMATION_DURATION) {
         radius = Math.round(elapsed * getWidth() / 2 / ANIMATION_DURATION);
         float shadowAlpha =
             (MAX_SHADOW_COLOR_ALPHA - MIN_SHADOW_COLOR_ALPHA) * elapsed / ANIMATION_DURATION
                 + MIN_SHADOW_COLOR_ALPHA;
         shadowColor = changeColorAlpha(mShadowColor, shadowAlpha);
       } else {
         radius = getWidth() / 2;
         shadowColor = changeColorAlpha(mShadowColor, MAX_SHADOW_COLOR_ALPHA);
       }
       postInvalidate();
       break;
     case StateTouchUp:
       if (elapsed < ANIMATION_DURATION) {
         int alpha = Math.round((ANIMATION_DURATION - elapsed) * 255 / ANIMATION_DURATION);
         ripplePaint.setAlpha(alpha);
         radius = getWidth() / 2 + Math.round(elapsed * getWidth() / 2 / ANIMATION_DURATION);
         float shadowAlpha =
             (MAX_SHADOW_COLOR_ALPHA - MIN_SHADOW_COLOR_ALPHA)
                     * (ANIMATION_DURATION - elapsed)
                     / ANIMATION_DURATION
                 + MIN_SHADOW_COLOR_ALPHA;
         shadowColor = changeColorAlpha(mShadowColor, shadowAlpha);
       } else {
         mState = StateNormal;
         radius = 0;
         ripplePaint.setAlpha(0);
         shadowColor = changeColorAlpha(mShadowColor, MIN_SHADOW_COLOR_ALPHA);
       }
       postInvalidate();
       break;
   }
   backgroundPaint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, shadowColor);
   canvas.drawRoundRect(getRectF(), mCornerRadius, mCornerRadius, backgroundPaint);
   canvas.save();
   if (mState == StateTouchDown || mState == StateTouchUp) {
     if (rippleClipPath == null) {
       rippleClipPath = new Path();
       rippleClipPath.addRoundRect(getRectF(), mCornerRadius, mCornerRadius, Path.Direction.CW);
     }
     canvas.clipPath(rippleClipPath);
   }
   canvas.drawCircle(mTouchPoint.x, mTouchPoint.y, radius, ripplePaint);
   canvas.restore();
   if (mText != null && mText.length() > 0) {
     int y = (int) (getHeight() / 2 - ((textPaint.descent() + textPaint.ascent()) / 2));
     canvas.drawText(mText.toString(), getWidth() / 2, y, textPaint);
   }
 }
  /** Draws the month days. */
  private void drawDays(Canvas canvas) {
    final TextPaint p = mDayPaint;
    final int headerHeight = mMonthHeight + mDayOfWeekHeight;
    final int rowHeight = mDayHeight;
    final int colWidth = mCellWidth;

    // Text is vertically centered within the row height.
    final float halfLineHeight = (p.ascent() + p.descent()) / 2f;
    int rowCenter = headerHeight + rowHeight / 2;

    for (int day = 1, col = findDayOffset(); day <= mDaysInMonth; day++) {
      final int colCenter = colWidth * col + colWidth / 2;
      final int colCenterRtl;
      if (isLayoutRtl()) {
        colCenterRtl = mPaddedWidth - colCenter;
      } else {
        colCenterRtl = colCenter;
      }

      int stateMask = 0;

      final boolean isDayEnabled = isDayEnabled(day);
      if (isDayEnabled) {
        stateMask |= StateSet.VIEW_STATE_ENABLED;
      }

      final boolean isDayActivated = mActivatedDay == day;
      if (isDayActivated) {
        stateMask |= StateSet.VIEW_STATE_ACTIVATED;

        // Adjust the circle to be centered on the row.
        canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, mDaySelectorPaint);
      } else if (mTouchedItem == day) {
        stateMask |= StateSet.VIEW_STATE_PRESSED;

        if (isDayEnabled) {
          // Adjust the circle to be centered on the row.
          canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, mDayHighlightPaint);
        }
      }

      final boolean isDayToday = mToday == day;
      final int dayTextColor;
      if (isDayToday && !isDayActivated) {
        dayTextColor = mDaySelectorPaint.getColor();
      } else {
        final int[] stateSet = StateSet.get(stateMask);
        dayTextColor = mDayTextColor.getColorForState(stateSet, 0);
      }
      p.setColor(dayTextColor);

      canvas.drawText(mDayFormatter.format(day), colCenterRtl, rowCenter - halfLineHeight, p);

      col++;

      if (col == DAYS_IN_WEEK) {
        col = 0;
        rowCenter += rowHeight;
      }
    }
  }
예제 #10
0
 @Override
 public void updateDrawState(@NonNull TextPaint tp) {
   initIfNecessary(tp.ascent());
   tp.baselineShift = shift;
 }