Example usage for android.graphics Canvas drawText

List of usage examples for android.graphics Canvas drawText

Introduction

In this page you can find the example usage for android.graphics Canvas drawText.

Prototype

public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) 

Source Link

Document

Draw the text, with origin at (x,y), using the specified paint.

Usage

From source file:me.ccrama.redditslide.Views.SubsamplingScaleImageView.java

/**
 * Draw method should not be called until the view has dimensions so the first calls are used as triggers to calculate
 * the scaling and tiling required. Once the view is setup, tiles are displayed as they are loaded.
 *//*  w  ww  . j  ava  2  s . c o  m*/
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    createPaints();

    // If image or view dimensions are not known yet, abort.
    if (sWidth == 0 || sHeight == 0 || getWidth() == 0 || getHeight() == 0) {
        return;
    }

    // When using tiles, on first render with no tile map ready, initialise it and kick off async base image loading.
    if (tileMap == null && decoder != null) {
        initialiseBaseLayer(getMaxBitmapDimensions(canvas));
    }

    // If image has been loaded or supplied as a bitmap, onDraw may be the first time the view has
    // dimensions and therefore the first opportunity to set scale and translate. If this call returns
    // false there is nothing to be drawn so return immediately.
    if (!checkReady()) {
        return;
    }

    // Set scale and translate before draw.
    preDraw();

    // If animating scale, calculate current scale and center with easing equations
    if (anim != null) {
        long scaleElapsed = System.currentTimeMillis() - anim.time;
        boolean finished = scaleElapsed > anim.duration;
        scaleElapsed = Math.min(scaleElapsed, anim.duration);
        setScale(ease(anim.easing, scaleElapsed, anim.scaleStart, anim.scaleEnd - anim.scaleStart,
                anim.duration));

        // Apply required animation to the focal point
        float vFocusNowX = ease(anim.easing, scaleElapsed, anim.vFocusStart.x,
                anim.vFocusEnd.x - anim.vFocusStart.x, anim.duration);
        float vFocusNowY = ease(anim.easing, scaleElapsed, anim.vFocusStart.y,
                anim.vFocusEnd.y - anim.vFocusStart.y, anim.duration);
        // Find out where the focal point is at this scale and adjust its position to follow the animation path
        vTranslate.x -= sourceToViewX(anim.sCenterEnd.x) - vFocusNowX;
        vTranslate.y -= sourceToViewY(anim.sCenterEnd.y) - vFocusNowY;

        // For translate anims, showing the image non-centered is never allowed, for scaling anims it is during the animation.
        fitToBounds(finished || (anim.scaleStart == anim.scaleEnd));
        refreshRequiredTiles(finished);
        if (finished) {
            if (anim.listener != null) {
                try {
                    anim.listener.onComplete();
                } catch (Exception e) {
                    Log.w(TAG, "Error thrown by animation listener", e);
                }
            }
            anim = null;
        }
        invalidate();
    }

    if (tileMap != null && isBaseLayerReady()) {

        // Optimum sample size for current scale
        int sampleSize = Math.min(fullImageSampleSize, calculateInSampleSize(scale));

        // First check for missing tiles - if there are any we need the base layer underneath to avoid gaps
        boolean hasMissingTiles = false;
        for (Map.Entry<Integer, List<Tile>> tileMapEntry : tileMap.entrySet()) {
            if (tileMapEntry.getKey() == sampleSize) {
                for (Tile tile : tileMapEntry.getValue()) {
                    if (tile.visible && (tile.loading || tile.bitmap == null)) {
                        hasMissingTiles = true;
                    }
                }
            }
        }

        // Render all loaded tiles. LinkedHashMap used for bottom up rendering - lower res tiles underneath.
        for (Map.Entry<Integer, List<Tile>> tileMapEntry : tileMap.entrySet()) {
            if (tileMapEntry.getKey() == sampleSize || hasMissingTiles) {
                for (Tile tile : tileMapEntry.getValue()) {
                    sourceToViewRect(tile.sRect, tile.vRect);
                    if (!tile.loading && tile.bitmap != null) {
                        if (tileBgPaint != null) {
                            canvas.drawRect(tile.vRect, tileBgPaint);
                        }
                        if (matrix == null) {
                            matrix = new Matrix();
                        }
                        matrix.reset();
                        setMatrixArray(srcArray, 0, 0, tile.bitmap.getWidth(), 0, tile.bitmap.getWidth(),
                                tile.bitmap.getHeight(), 0, tile.bitmap.getHeight());
                        if (getRequiredRotation() == ORIENTATION_0) {
                            setMatrixArray(dstArray, tile.vRect.left, tile.vRect.top, tile.vRect.right,
                                    tile.vRect.top, tile.vRect.right, tile.vRect.bottom, tile.vRect.left,
                                    tile.vRect.bottom);
                        } else if (getRequiredRotation() == ORIENTATION_90) {
                            setMatrixArray(dstArray, tile.vRect.right, tile.vRect.top, tile.vRect.right,
                                    tile.vRect.bottom, tile.vRect.left, tile.vRect.bottom, tile.vRect.left,
                                    tile.vRect.top);
                        } else if (getRequiredRotation() == ORIENTATION_180) {
                            setMatrixArray(dstArray, tile.vRect.right, tile.vRect.bottom, tile.vRect.left,
                                    tile.vRect.bottom, tile.vRect.left, tile.vRect.top, tile.vRect.right,
                                    tile.vRect.top);
                        } else if (getRequiredRotation() == ORIENTATION_270) {
                            setMatrixArray(dstArray, tile.vRect.left, tile.vRect.bottom, tile.vRect.left,
                                    tile.vRect.top, tile.vRect.right, tile.vRect.top, tile.vRect.right,
                                    tile.vRect.bottom);
                        }
                        matrix.setPolyToPoly(srcArray, 0, dstArray, 0, 4);
                        canvas.drawBitmap(tile.bitmap, matrix, bitmapPaint);
                        if (debug) {
                            canvas.drawRect(tile.vRect, debugPaint);
                        }
                    } else if (tile.loading && debug) {
                        canvas.drawText("LOADING", tile.vRect.left + 5, tile.vRect.top + 35, debugPaint);
                    }
                    if (tile.visible && debug) {
                        canvas.drawText(
                                "ISS " + tile.sampleSize + " RECT " + tile.sRect.top + "," + tile.sRect.left
                                        + "," + tile.sRect.bottom + "," + tile.sRect.right,
                                tile.vRect.left + 5, tile.vRect.top + 15, debugPaint);
                    }
                }
            }
        }

        if (debug) {
            canvas.drawText("Scale: " + String.format("%.2f", scale), 5, 15, debugPaint);
            canvas.drawText("Translate: " + String.format("%.2f", vTranslate.x) + ":"
                    + String.format("%.2f", vTranslate.y), 5, 35, debugPaint);
            PointF center = getCenter();
            canvas.drawText(
                    "Source center: " + String.format("%.2f", center.x) + ":" + String.format("%.2f", center.y),
                    5, 55, debugPaint);

            if (anim != null) {
                PointF vCenterStart = sourceToViewCoord(anim.sCenterStart);
                PointF vCenterEndRequested = sourceToViewCoord(anim.sCenterEndRequested);
                PointF vCenterEnd = sourceToViewCoord(anim.sCenterEnd);
                canvas.drawCircle(vCenterStart.x, vCenterStart.y, 10, debugPaint);
                canvas.drawCircle(vCenterEndRequested.x, vCenterEndRequested.y, 20, debugPaint);
                canvas.drawCircle(vCenterEnd.x, vCenterEnd.y, 25, debugPaint);
                canvas.drawCircle(getWidth() / 2, getHeight() / 2, 30, debugPaint);
            }
        }

    } else if (bitmap != null) {

        float xScale = scale, yScale = scale;
        if (bitmapIsPreview) {
            xScale = scale * ((float) sWidth / bitmap.getWidth());
            yScale = scale * ((float) sHeight / bitmap.getHeight());
        }

        if (matrix == null) {
            matrix = new Matrix();
        }
        matrix.reset();
        matrix.postScale(xScale, yScale);
        matrix.postRotate(getRequiredRotation());
        matrix.postTranslate(vTranslate.x, vTranslate.y);

        if (getRequiredRotation() == ORIENTATION_180) {
            matrix.postTranslate(scale * sWidth, scale * sHeight);
        } else if (getRequiredRotation() == ORIENTATION_90) {
            matrix.postTranslate(scale * sHeight, 0);
        } else if (getRequiredRotation() == ORIENTATION_270) {
            matrix.postTranslate(0, scale * sWidth);
        }

        if (tileBgPaint != null) {
            if (sRect == null) {
                sRect = new RectF();
            }
            sRect.set(0f, 0f, sWidth, sHeight);
            matrix.mapRect(sRect);
            canvas.drawRect(sRect, tileBgPaint);
        }
        canvas.drawBitmap(bitmap, matrix, bitmapPaint);

    }
}

From source file:com.gigamole.library.NavigationTabBar.java

@Override
protected void onDraw(final Canvas canvas) {
    if (mCanvas == null || mPointerCanvas == null || mIconsCanvas == null)
        return;//w  ww  .j a va 2  s. co  m

    // Reset and clear canvases
    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mPointerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

    // Get pointer badge margin for gravity
    final float pointerBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0f;

    // Draw our model colors
    for (int i = 0; i < mModels.size(); i++) {
        mPaint.setColor(mModels.get(i).getColor());

        if (mIsHorizontalOrientation) {
            final float left = mModelSize * i;
            final float right = left + mModelSize;
            mCanvas.drawRect(left, pointerBadgeMargin, right, mBounds.height() + pointerBadgeMargin, mPaint);
        } else {
            final float top = mModelSize * i;
            final float bottom = top + mModelSize;
            mCanvas.drawRect(0.0f, top, mBounds.width(), bottom, mPaint);
        }
    }

    // Set bound of pointer
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, pointerBadgeMargin, mPointerRightBottom,
                mBounds.height() + pointerBadgeMargin);
    else
        mPointerBounds.set(0.0f, mPointerLeftTop, mBounds.width(), mPointerRightBottom);

    // Draw pointer for model colors
    if (mCornersRadius == 0)
        mPointerCanvas.drawRect(mPointerBounds, mPaint);
    else
        mPointerCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mPaint);

    // Draw pointer into main canvas
    mCanvas.drawBitmap(mPointerBitmap, 0.0f, 0.0f, mPointerPaint);

    // Draw model icons
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Variables to center our icons
        final float leftOffset;
        final float topOffset;
        final float matrixCenterX;
        final float matrixCenterY;

        // Set vars for icon when model with title or without
        final float iconMarginTitleHeight = mIconSize + mTitleMargin + mModelTitleSize;
        final float leftTitleOffset = (mModelSize * i) + (mModelSize * 0.5f);
        final float topTitleOffset = mBounds.height() - (mBounds.height() - iconMarginTitleHeight) * 0.5f;

        if (mIsHorizontalOrientation) {
            leftOffset = (mModelSize * i) + (mModelSize - model.mIcon.getWidth()) * 0.5f;
            topOffset = (mBounds.height() - model.mIcon.getHeight()) * 0.5f;

            matrixCenterX = leftOffset + model.mIcon.getWidth() * 0.5f;
            matrixCenterY = topOffset + model.mIcon.getHeight() * 0.5f
                    + (mIsTitled && mTitleMode == TitleMode.ALL ? mTitleMargin * 0.5f : 0.0f);
        } else {
            leftOffset = (mBounds.width() - model.mIcon.getWidth()) * 0.5f;
            topOffset = (mModelSize * i) + (mModelSize - model.mIcon.getHeight()) * 0.5f;

            matrixCenterX = leftOffset + model.mIcon.getWidth() * 0.5f;
            matrixCenterY = topOffset + model.mIcon.getHeight() * 0.5f;
        }

        // Title translate position
        final float titleTranslate = -model.mIcon.getHeight() + topTitleOffset - mTitleMargin * 0.5f;

        // Translate icon to model center
        model.mIconMatrix.setTranslate(leftOffset,
                (mIsTitled && mTitleMode == TitleMode.ALL) ? titleTranslate : topOffset);

        // Get interpolated fraction for left last and current models
        final float interpolation = mResizeInterpolator.getResizeInterpolation(mFraction, true);
        final float lastInterpolation = mResizeInterpolator.getResizeInterpolation(mFraction, false);

        // Scale value relative to interpolation
        final float matrixScale = model.mActiveIconScaleBy * interpolation;
        final float matrixLastScale = model.mActiveIconScaleBy * lastInterpolation;

        // Get title alpha relative to interpolation
        final int titleAlpha = (int) (MAX_ALPHA * interpolation);
        final int titleLastAlpha = MAX_ALPHA - (int) (MAX_ALPHA * lastInterpolation);
        // Get title scale relative to interpolation
        final float titleScale = MAX_FRACTION + (interpolation * TITLE_ACTIVE_SCALE_BY);
        final float titleLastScale = (MAX_FRACTION + TITLE_ACTIVE_SCALE_BY)
                - (lastInterpolation * TITLE_ACTIVE_SCALE_BY);

        // Check if we handle models from touch on NTP or from ViewPager
        // There is a strange logic of ViewPager onPageScrolled method, so it is
        if (mIsSetIndexFromTabBar) {
            if (mIndex == i)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (mLastIndex == i)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, matrixCenterX, matrixCenterY);
        } else {
            if (i != mIndex && i != mIndex + 1)
                updateInactiveModel(model, leftOffset, topOffset, matrixCenterX, matrixCenterY);
            else if (i == mIndex + 1)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (i == mIndex)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
        }

        // Draw model icon
        mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        if (mIsTitled)
            mIconsCanvas.drawText(isInEditMode() ? PREVIEW_TITLE : model.getTitle(), leftTitleOffset,
                    topTitleOffset, mModelTitlePaint);
    }

    // Draw pointer with active color to wrap out active icon
    if (mCornersRadius == 0)
        mIconsCanvas.drawRect(mPointerBounds, mIconPointerPaint);
    else
        mIconsCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);

    // Draw general bitmap
    canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
    // Draw icons bitmap on top
    canvas.drawBitmap(mIconsBitmap, 0.0f, pointerBadgeMargin, null);

    // If is not badged, exit
    if (!mIsBadged)
        return;

    // Model badge margin and offset relative to gravity mode
    final float modelBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : mBounds.height();
    final float modelBadgeOffset = mBadgeGravity == BadgeGravity.TOP ? 0.0f : mBounds.height() - mBadgeMargin;

    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Set preview badge title
        if (isInEditMode() || TextUtils.isEmpty(model.getBadgeTitle()))
            model.setBadgeTitle(PREVIEW_BADGE);

        // Set badge title bounds
        mBadgePaint.setTextSize(mBadgeTitleSize * model.mBadgeFraction);
        mBadgePaint.getTextBounds(model.getBadgeTitle(), 0, model.getBadgeTitle().length(), mBadgeBounds);

        // Get horizontal and vertical padding for bg
        final float horizontalPadding = mBadgeTitleSize * BADGE_HORIZONTAL_FRACTION;
        final float verticalPadding = horizontalPadding * BADGE_VERTICAL_FRACTION;

        // Set horizontal badge offset
        final float badgeBoundsHorizontalOffset = (mModelSize * i)
                + (mModelSize * mBadgePosition.mPositionFraction);

        // If is badge title only one char, so create circle else round rect
        if (model.getBadgeTitle().length() == 1) {
            final float badgeMargin = mBadgeMargin * model.mBadgeFraction;
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - badgeMargin, modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset + badgeMargin, modelBadgeMargin + badgeMargin);
        } else
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - mBadgeBounds.centerX() - horizontalPadding,
                    modelBadgeMargin - (mBadgeMargin * model.mBadgeFraction),
                    badgeBoundsHorizontalOffset + mBadgeBounds.centerX() + horizontalPadding,
                    modelBadgeOffset + (verticalPadding * 2.0f) + mBadgeBounds.height());

        // Set color and alpha for badge bg
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else
            mBadgePaint.setColor(mActiveColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set corners to round rect for badge bg and draw
        final float cornerRadius = mBgBadgeBounds.height() * 0.5f;
        canvas.drawRoundRect(mBgBadgeBounds, cornerRadius, cornerRadius, mBadgePaint);

        // Set color and alpha for badge title
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else
            mBadgePaint.setColor(model.getColor());
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set badge title center position and draw title
        final float badgeHalfHeight = mBadgeBounds.height() * 0.5f;
        float badgeVerticalOffset = (mBgBadgeBounds.height() * 0.5f) + badgeHalfHeight - mBadgeBounds.bottom
                + modelBadgeOffset;
        canvas.drawText(model.getBadgeTitle(), badgeBoundsHorizontalOffset,
                badgeVerticalOffset + mBadgeBounds.height() - (mBadgeBounds.height() * model.mBadgeFraction),
                mBadgePaint);
    }
}

From source file:talex.zsw.baselibrary.widget.NavigationTabBar.java

@Override
protected void onDraw(final Canvas canvas) {
    if (mCanvas == null || mPointerCanvas == null || mIconsCanvas == null)
        return;//from www. j ava  2 s  .c o  m

    // Reset and clear canvases
    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mPointerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

    // Get pointer badge margin for gravity
    final float pointerBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0f;

    // Draw our model colors
    for (int i = 0; i < mModels.size(); i++) {
        mPaint.setColor(mModels.get(i).getColor());

        if (mIsHorizontalOrientation) {
            final float left = mModelSize * i;
            final float right = left + mModelSize;
            mCanvas.drawRect(left, pointerBadgeMargin, right, mBounds.height() + pointerBadgeMargin, mPaint);
        } else {
            final float top = mModelSize * i;
            final float bottom = top + mModelSize;
            mCanvas.drawRect(0.0f, top, mBounds.width(), bottom, mPaint);
        }
    }

    // Set bound of pointer
    if (mIsHorizontalOrientation) {
        mPointerBounds.set(mPointerLeftTop, pointerBadgeMargin, mPointerRightBottom,
                mBounds.height() + pointerBadgeMargin);
    } else {
        mPointerBounds.set(0.0f, mPointerLeftTop, mBounds.width(), mPointerRightBottom);
    }

    // Draw pointer for model colors
    if (mCornersRadius == 0) {
        mPointerCanvas.drawRect(mPointerBounds, mPaint);
    } else {
        mPointerCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mPaint);
    }

    // Draw pointer into main canvas
    mCanvas.drawBitmap(mPointerBitmap, 0.0f, 0.0f, mPointerPaint);

    // Draw model icons
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Variables to center our icons
        final float leftOffset;
        final float topOffset;
        final float matrixCenterX;
        final float matrixCenterY;

        // Set vars for icon when model with title or without
        final float iconMarginTitleHeight = mIconSize + mTitleMargin + mModelTitleSize;
        final float leftTitleOffset = (mModelSize * i) + (mModelSize * 0.5f);
        final float topTitleOffset = mBounds.height() - (mBounds.height() - iconMarginTitleHeight) * 0.5f;

        if (mIsHorizontalOrientation) {
            leftOffset = (mModelSize * i) + (mModelSize - model.mIcon.getWidth()) * 0.5f;
            topOffset = (mBounds.height() - model.mIcon.getHeight()) * 0.5f;

            matrixCenterX = leftOffset + model.mIcon.getWidth() * 0.5f;
            matrixCenterY = topOffset + model.mIcon.getHeight() * 0.5f
                    + (mIsTitled && mTitleMode == TitleMode.ALL ? mTitleMargin * 0.5f : 0.0f);
        } else {
            leftOffset = (mBounds.width() - model.mIcon.getWidth()) * 0.5f;
            topOffset = (mModelSize * i) + (mModelSize - model.mIcon.getHeight()) * 0.5f;

            matrixCenterX = leftOffset + model.mIcon.getWidth() * 0.5f;
            matrixCenterY = topOffset + model.mIcon.getHeight() * 0.5f;
        }

        // Title translate position
        final float titleTranslate = -model.mIcon.getHeight() + topTitleOffset - mTitleMargin * 0.5f;

        // Translate icon to model center
        model.mIconMatrix.setTranslate(leftOffset,
                (mIsTitled && mTitleMode == TitleMode.ALL) ? titleTranslate : topOffset);

        // Get interpolated fraction for left last and current models
        final float interpolation = mResizeInterpolator.getResizeInterpolation(mFraction, true);
        final float lastInterpolation = mResizeInterpolator.getResizeInterpolation(mFraction, false);

        // Scale value relative to interpolation
        final float matrixScale = model.mActiveIconScaleBy * interpolation;
        final float matrixLastScale = model.mActiveIconScaleBy * lastInterpolation;

        // Get title alpha relative to interpolation
        final int titleAlpha = (int) (MAX_ALPHA * interpolation);
        final int titleLastAlpha = MAX_ALPHA - (int) (MAX_ALPHA * lastInterpolation);
        // Get title scale relative to interpolation
        final float titleScale = MAX_FRACTION + (interpolation * TITLE_ACTIVE_SCALE_BY);
        final float titleLastScale = (MAX_FRACTION + TITLE_ACTIVE_SCALE_BY)
                - (lastInterpolation * TITLE_ACTIVE_SCALE_BY);

        // Check if we handle models from touch on NTP or from ViewPager
        // There is a strange logic of ViewPager onPageScrolled method, so it is
        if (mIsSetIndexFromTabBar) {
            if (mIndex == i) {
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            } else if (mLastIndex == i) {
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            } else {
                updateInactiveModel(model, leftOffset, topOffset, matrixCenterX, matrixCenterY);
            }
        } else {
            if (i != mIndex && i != mIndex + 1) {
                updateInactiveModel(model, leftOffset, topOffset, matrixCenterX, matrixCenterY);
            } else if (i == mIndex + 1) {
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            } else if (i == mIndex) {
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            }
        }

        // Draw model icon
        mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        if (mIsTitled) {
            mIconsCanvas.drawText(isInEditMode() ? PREVIEW_TITLE : model.getTitle(), leftTitleOffset,
                    topTitleOffset, mModelTitlePaint);
        }
    }

    // Draw pointer with active color to wrap out active icon
    if (mCornersRadius == 0) {
        mIconsCanvas.drawRect(mPointerBounds, mIconPointerPaint);
    } else {
        mIconsCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
    }

    // Draw general bitmap
    canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
    // Draw icons bitmap on top
    canvas.drawBitmap(mIconsBitmap, 0.0f, pointerBadgeMargin, null);

    // If is not badged, exit
    if (!mIsBadged)
        return;

    // Model badge margin and offset relative to gravity mode
    final float modelBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : mBounds.height();
    final float modelBadgeOffset = mBadgeGravity == BadgeGravity.TOP ? 0.0f : mBounds.height() - mBadgeMargin;

    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Set preview badge title
        if (isInEditMode() || TextUtils.isEmpty(model.getBadgeTitle())) {
            model.setBadgeTitle(PREVIEW_BADGE);
        }

        // Set badge title bounds
        mBadgePaint.setTextSize(mBadgeTitleSize * model.mBadgeFraction);
        mBadgePaint.getTextBounds(model.getBadgeTitle(), 0, model.getBadgeTitle().length(), mBadgeBounds);

        // Get horizontal and vertical padding for bg
        final float horizontalPadding = mBadgeTitleSize * BADGE_HORIZONTAL_FRACTION;
        final float verticalPadding = horizontalPadding * BADGE_VERTICAL_FRACTION;

        // Set horizontal badge offset
        final float badgeBoundsHorizontalOffset = (mModelSize * i)
                + (mModelSize * mBadgePosition.mPositionFraction);

        // If is badge title only one char, so create circle else round rect
        if (model.getBadgeTitle().length() == 1) {
            final float badgeMargin = mBadgeMargin * model.mBadgeFraction;
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - badgeMargin, modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset + badgeMargin, modelBadgeMargin + badgeMargin);
        } else {
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - mBadgeBounds.centerX() - horizontalPadding,
                    modelBadgeMargin - (mBadgeMargin * model.mBadgeFraction),
                    badgeBoundsHorizontalOffset + mBadgeBounds.centerX() + horizontalPadding,
                    modelBadgeOffset + (verticalPadding * 2.0f) + mBadgeBounds.height());
        }

        // Set color and alpha for badge bg
        if (model.mBadgeFraction == MIN_FRACTION) {
            mBadgePaint.setColor(Color.TRANSPARENT);
        } else {
            mBadgePaint.setColor(mActiveColor);
        }
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set corners to round rect for badge bg and draw
        final float cornerRadius = mBgBadgeBounds.height() * 0.5f;
        canvas.drawRoundRect(mBgBadgeBounds, cornerRadius, cornerRadius, mBadgePaint);

        // Set color and alpha for badge title
        if (model.mBadgeFraction == MIN_FRACTION) {
            mBadgePaint.setColor(Color.TRANSPARENT);
        } else {
            mBadgePaint.setColor(model.getColor());
        }
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set badge title center position and draw title
        final float badgeHalfHeight = mBadgeBounds.height() * 0.5f;
        float badgeVerticalOffset = (mBgBadgeBounds.height() * 0.5f) + badgeHalfHeight - mBadgeBounds.bottom
                + modelBadgeOffset;
        canvas.drawText(model.getBadgeTitle(), badgeBoundsHorizontalOffset,
                badgeVerticalOffset + mBadgeBounds.height() - (mBadgeBounds.height() * model.mBadgeFraction),
                mBadgePaint);
    }
}

From source file:com.gigamole.library.ntb.NavigationTabBar.java

@SuppressWarnings("ConstantConditions")
@Override/*from   w  w w . j av  a  2s  .  c om*/
protected void onDraw(final Canvas canvas) {
    if (mBackground != null)
        canvas.drawBitmap(mBackground, 0.0F, mBadgeGravity == BadgeGravity.TOP ? getBadgeMargin() : 0.0F, null);

    if (mCanvas == null || mPointerCanvas == null || mIconsCanvas == null || mTitlesCanvas == null)
        return;

    // Reset and clear canvases
    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mPointerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    if (mIsTitled)
        mTitlesCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

    // Get pointer badge margin for gravity
    final float pointerBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;

    // Draw our model colors
    for (int i = 0; i < mModels.size(); i++) {
        mPaint.setColor(mModels.get(i).getColor());

        if (mIsHorizontalOrientation) {
            final float left = mModelSize * i;
            final float right = left + mModelSize;
            mCanvas.drawRect(left, pointerBadgeMargin, right, mBounds.height() + pointerBadgeMargin, mPaint);
        } else {
            final float top = mModelSize * i;
            final float bottom = top + mModelSize;
            mCanvas.drawRect(0.0F, top, mBounds.width(), bottom, mPaint);
        }
    }

    // Set bound of pointer
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, pointerBadgeMargin, mPointerRightBottom,
                mBounds.height() + pointerBadgeMargin);
    else
        mPointerBounds.set(0.0F, mPointerLeftTop, mBounds.width(), mPointerRightBottom);

    // Draw pointer for model colors
    if (mCornersRadius == 0)
        mPointerCanvas.drawRect(mPointerBounds, mPaint);
    else
        mPointerCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mPaint);

    // Draw pointer into main canvas
    mCanvas.drawBitmap(mPointerBitmap, 0.0F, 0.0F, mPointerPaint);

    // Set vars for icon when model with title or without
    final float iconMarginTitleHeight = mIconSize + mTitleMargin + mModelTitleSize;

    // Draw model icons
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Variables to center our icons
        final float leftOffset;
        final float topOffset;
        final float matrixCenterX;
        final float matrixCenterY;

        // Set offset to titles
        final float leftTitleOffset = (mModelSize * i) + (mModelSize * 0.5F);
        final float topTitleOffset = mBounds.height() - (mBounds.height() - iconMarginTitleHeight) * 0.5F;

        if (mIsHorizontalOrientation) {
            leftOffset = (mModelSize * i) + (mModelSize - model.mIcon.getWidth()) * 0.5F;
            topOffset = (mBounds.height() - model.mIcon.getHeight()) * 0.5F;
        } else {
            leftOffset = (mBounds.width() - (float) model.mIcon.getWidth()) * 0.5F;
            topOffset = (mModelSize * i) + (mModelSize - (float) model.mIcon.getHeight()) * 0.5F;
        }

        matrixCenterX = leftOffset + (float) model.mIcon.getWidth() * 0.5F;
        matrixCenterY = topOffset + (float) model.mIcon.getHeight() * 0.5F;

        // Title translate position
        final float titleTranslate = topOffset - model.mIcon.getHeight() * TITLE_MARGIN_SCALE_FRACTION;

        // Translate icon to model center
        model.mIconMatrix.setTranslate(leftOffset,
                (mIsTitled && mTitleMode == TitleMode.ALL) ? titleTranslate : topOffset);

        // Get interpolated fraction for left last and current models
        final float interpolation = mResizeInterpolator.getResizeInterpolation(mFraction, true);
        final float lastInterpolation = mResizeInterpolator.getResizeInterpolation(mFraction, false);

        // Scale value relative to interpolation
        final float matrixScale = model.mActiveIconScaleBy * (mIsScaled ? interpolation : NON_SCALED_FRACTION);
        final float matrixLastScale = model.mActiveIconScaleBy
                * (mIsScaled ? lastInterpolation : (MAX_FRACTION - NON_SCALED_FRACTION));

        // Get title alpha relative to interpolation
        final int titleAlpha = (int) (MAX_ALPHA * interpolation);
        final int titleLastAlpha = MAX_ALPHA - (int) (MAX_ALPHA * lastInterpolation);
        // Get title scale relative to interpolation
        final float titleScale = MAX_FRACTION
                + ((mIsScaled ? interpolation : NON_SCALED_FRACTION) * TITLE_ACTIVE_SCALE_BY);
        final float titleLastScale = mIsScaled
                ? (MAX_FRACTION + TITLE_ACTIVE_SCALE_BY) - (lastInterpolation * TITLE_ACTIVE_SCALE_BY)
                : titleScale;

        mIconPaint.setAlpha(MAX_ALPHA);
        if (model.mSelectedIcon != null)
            mSelectedIconPaint.setAlpha(MAX_ALPHA);

        // Check if we handle models from touch on NTB or from ViewPager
        // There is a strange logic
        // of ViewPager onPageScrolled method, so it is
        if (mIsSetIndexFromTabBar) {
            if (mIndex == i)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (mLastIndex == i)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        } else {
            if (i != mIndex && i != mIndex + 1)
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
            else if (i == mIndex + 1)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (i == mIndex)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
        }

        // Draw original model icon
        if (model.mSelectedIcon == null) {
            mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        } else {
            if (mIconPaint.getAlpha() != MIN_ALPHA)
                // Draw original icon when is visible
                mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        }
        // Draw selected icon when exist and visible
        if (model.mSelectedIcon != null && mSelectedIconPaint.getAlpha() != MIN_ALPHA)
            mIconsCanvas.drawBitmap(model.mSelectedIcon, model.mIconMatrix, mSelectedIconPaint);

        if (mIsTitled)
            mTitlesCanvas.drawText(isInEditMode() ? PREVIEW_TITLE : model.getTitle(), leftTitleOffset,
                    topTitleOffset, mModelTitlePaint);
    }

    // Reset pointer bounds for icons and titles
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, 0.0F, mPointerRightBottom, mBounds.height());
    if (mCornersRadius == 0) {
        if (mIsTinted)
            mIconsCanvas.drawRect(mPointerBounds, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRect(mPointerBounds, mIconPointerPaint);
    } else {
        if (mIsTinted)
            mIconsCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
    }

    // Draw general bitmap
    canvas.drawBitmap(mBitmap, 0.0F, 0.0F, null);
    // Draw icons bitmap on top
    canvas.drawBitmap(mIconsBitmap, 0.0F, pointerBadgeMargin, null);
    // Draw titles bitmap on top
    if (mIsTitled)
        canvas.drawBitmap(mTitlesBitmap, 0.0F, pointerBadgeMargin, null);

    // If is not badged, exit
    if (!mIsBadged)
        return;

    // Model badge margin and offset relative to gravity mode
    final float modelBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : mBounds.height();
    final float modelBadgeOffset = mBadgeGravity == BadgeGravity.TOP ? 0.0F : mBounds.height() - mBadgeMargin;

    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Set preview badge title
        if (isInEditMode() || TextUtils.isEmpty(model.getBadgeTitle()))
            model.setBadgeTitle(PREVIEW_BADGE);

        // Set badge title bounds
        mBadgePaint.setTextSize(mBadgeTitleSize * model.mBadgeFraction);
        mBadgePaint.getTextBounds(model.getBadgeTitle(), 0, model.getBadgeTitle().length(), mBadgeBounds);

        // Get horizontal and vertical padding for bg
        final float horizontalPadding = mBadgeTitleSize * BADGE_HORIZONTAL_FRACTION;
        final float verticalPadding = horizontalPadding * BADGE_VERTICAL_FRACTION;

        // Set horizontal badge offset
        final float badgeBoundsHorizontalOffset = (mModelSize * i)
                + (mModelSize * mBadgePosition.mPositionFraction);

        // If is badge title only one char, so create circle else round rect
        final float badgeMargin = mBadgeMargin * model.mBadgeFraction;
        if (model.getBadgeTitle().length() == 1) {
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - badgeMargin, modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset + badgeMargin, modelBadgeMargin + badgeMargin);
        } else
            mBgBadgeBounds.set(
                    badgeBoundsHorizontalOffset
                            - Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset
                            + Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeOffset + (verticalPadding * 2.0F) + mBadgeBounds.height());

        // Set color and alpha for badge bg
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else
            mBadgePaint.setColor(mBadgeBgColor == 0 ? mActiveColor : mBadgeBgColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set corners to round rect for badge bg and draw
        final float cornerRadius = mBgBadgeBounds.height() * 0.5F;
        canvas.drawRoundRect(mBgBadgeBounds, cornerRadius, cornerRadius, mBadgePaint);

        // Set color and alpha for badge title
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else //noinspection ResourceAsColor
            mBadgePaint.setColor(mBadgeTitleColor == 0 ? model.getColor() : mBadgeTitleColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set badge title center position and draw title
        final float badgeHalfHeight = mBadgeBounds.height() * 0.5F;
        float badgeVerticalOffset = (mBgBadgeBounds.height() * 0.5F) + badgeHalfHeight - mBadgeBounds.bottom
                + modelBadgeOffset;
        canvas.drawText(model.getBadgeTitle(), badgeBoundsHorizontalOffset,
                badgeVerticalOffset + mBadgeBounds.height() - (mBadgeBounds.height() * model.mBadgeFraction),
                mBadgePaint);
    }
}

From source file:cn.oddcloud.www.navigationtabbar.ntb.NavigationTabBar.java

@SuppressWarnings("ConstantConditions")
@Override/*w  ww.  j a  v a 2s  .c  om*/
protected void onDraw(final Canvas canvas) {
    // Get height of NTB with badge on nor
    final int mBadgedHeight = (int) (mBounds.height() + mBadgeMargin);

    // Set main canvas
    if (mBitmap == null || mBitmap.isRecycled()) {
        mBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmap);
    }
    // Set pointer canvas
    if (mPointerBitmap == null || mPointerBitmap.isRecycled()) {
        mPointerBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mPointerCanvas.setBitmap(mPointerBitmap);
    }
    // Set icons canvas
    if (mIconsBitmap == null || mIconsBitmap.isRecycled()) {
        mIconsBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mIconsCanvas.setBitmap(mIconsBitmap);
    }
    // Set titles canvas
    if (mIsTitled) {
        if (mTitlesBitmap == null || mTitlesBitmap.isRecycled()) {
            mTitlesBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
            mTitlesCanvas.setBitmap(mTitlesBitmap);
        }
    } else
        mTitlesBitmap = null;

    // Reset and clear canvases
    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mPointerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    if (mIsTitled)
        mTitlesCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

    if (mCornersRadius == 0)
        canvas.drawRect(mBgBounds, mBgPaint);
    else
        canvas.drawRoundRect(mBgBounds, mCornersRadius, mCornersRadius, mBgPaint);

    // Get pointer badge margin for gravity
    final float barBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;

    // Draw our model colors
    for (int i = 0; i < mModels.size(); i++) {
        mPaint.setColor(mModels.get(i).getColor());

        if (mIsHorizontalOrientation) {
            final float left = mModelSize * i;
            final float right = left + mModelSize;
            mCanvas.drawRect(left, barBadgeMargin, right, mBounds.height() + barBadgeMargin, mPaint);
        } else {
            final float top = mModelSize * i;
            final float bottom = top + mModelSize;
            mCanvas.drawRect(0.0F, top, mBounds.width(), bottom, mPaint);
        }
    }

    // Set bound of pointer
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, barBadgeMargin, mPointerRightBottom,
                mBounds.height() + barBadgeMargin);
    else
        mPointerBounds.set(0.0F, mPointerLeftTop, mBounds.width(), mPointerRightBottom);

    // Draw pointer for model colors
    if (mCornersRadius == 0)
        mPointerCanvas.drawRect(mPointerBounds, mPaint);
    else
        mPointerCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mPaint);

    // Draw pointer into main canvas
    mCanvas.drawBitmap(mPointerBitmap, 0.0F, 0.0F, mPointerPaint);

    // Set vars for icon when model with title or without
    final float iconMarginTitleHeight = mIconSize + mTitleMargin + mModelTitleSize;

    // Draw model icons
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Variables to center our icons
        final float leftOffset;
        final float topOffset;
        final float matrixCenterX;
        final float matrixCenterY;

        // Set offset to titles
        final float leftTitleOffset = (mModelSize * i) + (mModelSize * 0.5F);
        final float topTitleOffset = mBounds.height() - (mBounds.height() - iconMarginTitleHeight) * 0.5F;

        if (mIsHorizontalOrientation) {
            leftOffset = (mModelSize * i) + (mModelSize - model.mIcon.getWidth()) * 0.5F;
            topOffset = (mBounds.height() - model.mIcon.getHeight()) * 0.5F;
        } else {
            leftOffset = (mBounds.width() - (float) model.mIcon.getWidth()) * 0.5F;
            topOffset = (mModelSize * i) + (mModelSize - (float) model.mIcon.getHeight()) * 0.5F;
        }

        matrixCenterX = leftOffset + (float) model.mIcon.getWidth() * 0.5F;
        matrixCenterY = topOffset + (float) model.mIcon.getHeight() * 0.5F;

        // Title translate position
        final float titleTranslate = topOffset - model.mIcon.getHeight() * TITLE_MARGIN_SCALE_FRACTION;

        // Translate icon to model center
        model.mIconMatrix.setTranslate(leftOffset,
                (mIsTitled && mTitleMode == TitleMode.ALL) ? titleTranslate : topOffset);

        // Get interpolated fraction for left last and current models
        final float interpolation = mResizeInterpolator.getResizeInterpolation(mFraction, true);
        final float lastInterpolation = mResizeInterpolator.getResizeInterpolation(mFraction, false);

        // Scale value relative to interpolation
        final float matrixScale = model.mActiveIconScaleBy * (mIsScaled ? interpolation : NON_SCALED_FRACTION);
        final float matrixLastScale = model.mActiveIconScaleBy
                * (mIsScaled ? lastInterpolation : (MAX_FRACTION - NON_SCALED_FRACTION));

        // Get title alpha relative to interpolation
        final int titleAlpha = (int) (MAX_ALPHA * interpolation);
        final int titleLastAlpha = MAX_ALPHA - (int) (MAX_ALPHA * lastInterpolation);
        // Get title scale relative to interpolation
        final float titleScale = MAX_FRACTION
                + ((mIsScaled ? interpolation : NON_SCALED_FRACTION) * TITLE_ACTIVE_SCALE_BY);
        final float titleLastScale = mIsScaled
                ? (MAX_FRACTION + TITLE_ACTIVE_SCALE_BY) - (lastInterpolation * TITLE_ACTIVE_SCALE_BY)
                : titleScale;

        mIconPaint.setAlpha(MAX_ALPHA);
        if (model.mSelectedIcon != null)
            mSelectedIconPaint.setAlpha(MAX_ALPHA);

        // Check if we handle models from touch on NTB or from ViewPager
        // There is a strange logic
        // of ViewPager onPageScrolled method, so it is
        if (mIsSetIndexFromTabBar) {
            if (mIndex == i)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (mLastIndex == i)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        } else {
            if (i == mIndex + 1)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (i == mIndex)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        }

        // Draw original model icon
        if (model.mSelectedIcon == null) {
            if (model.mIcon != null && !model.mIcon.isRecycled())
                mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        } else {
            if (mIconPaint.getAlpha() != MIN_ALPHA && model.mIcon != null && !model.mIcon.isRecycled())
                // Draw original icon when is visible
                mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        }
        // Draw selected icon when exist and visible
        if (mSelectedIconPaint.getAlpha() != MIN_ALPHA && model.mSelectedIcon != null
                && !model.mSelectedIcon.isRecycled())
            mIconsCanvas.drawBitmap(model.mSelectedIcon, model.mIconMatrix, mSelectedIconPaint);

        if (mIsTitled)
            mTitlesCanvas.drawText(isInEditMode() ? PREVIEW_TITLE : model.getTitle(), leftTitleOffset,
                    topTitleOffset, mModelTitlePaint);
    }

    // Reset pointer bounds for icons and titles
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, 0.0F, mPointerRightBottom, mBounds.height());
    if (mCornersRadius == 0) {
        if (mIsTinted)
            mIconsCanvas.drawRect(mPointerBounds, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRect(mPointerBounds, mIconPointerPaint);
    } else {
        if (mIsTinted)
            mIconsCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
    }

    // Draw general bitmap
    canvas.drawBitmap(mBitmap, 0.0F, 0.0F, null);
    // Draw icons bitmap on top
    canvas.drawBitmap(mIconsBitmap, 0.0F, barBadgeMargin, null);
    // Draw titles bitmap on top
    if (mIsTitled)
        canvas.drawBitmap(mTitlesBitmap, 0.0F, barBadgeMargin, null);

    // If is not badged, exit
    if (!mIsBadged)
        return;

    // Model badge margin and offset relative to gravity mode
    final float modelBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : mBounds.height();
    final float modelBadgeOffset = mBadgeGravity == BadgeGravity.TOP ? 0.0F : mBounds.height() - mBadgeMargin;

    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Set preview badge title
        if (isInEditMode() || TextUtils.isEmpty(model.getBadgeTitle()))
            model.setBadgeTitle(PREVIEW_BADGE);

        // Set badge title bounds
        mBadgePaint.setTextSize(mBadgeTitleSize * model.mBadgeFraction);
        mBadgePaint.getTextBounds(model.getBadgeTitle(), 0, model.getBadgeTitle().length(), mBadgeBounds);

        // Get horizontal and vertical padding for bg
        final float horizontalPadding = mBadgeTitleSize * BADGE_HORIZONTAL_FRACTION;
        final float verticalPadding = horizontalPadding * BADGE_VERTICAL_FRACTION;

        // Set horizontal badge offset
        final float badgeBoundsHorizontalOffset = (mModelSize * i)
                + (mModelSize * mBadgePosition.mPositionFraction);

        // If is badge title only one char, so create circle else round rect
        final float badgeMargin = mBadgeMargin * model.mBadgeFraction;
        if (model.getBadgeTitle().length() == 1) {
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - badgeMargin, modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset + badgeMargin, modelBadgeMargin + badgeMargin);
        } else
            mBgBadgeBounds.set(
                    badgeBoundsHorizontalOffset
                            - Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset
                            + Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeOffset + (verticalPadding * 2.0F) + mBadgeBounds.height());

        // Set color and alpha for badge bg
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else
            mBadgePaint.setColor(mBadgeBgColor == AUTO_COLOR ? mActiveColor : mBadgeBgColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set corners to round rect for badge bg and draw
        final float cornerRadius = mBgBadgeBounds.height() * 0.5F;
        canvas.drawRoundRect(mBgBadgeBounds, cornerRadius, cornerRadius, mBadgePaint);

        // Set color and alpha for badge title
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else //noinspection ResourceAsColor
            mBadgePaint.setColor(mBadgeTitleColor == AUTO_COLOR ? model.getColor() : mBadgeTitleColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set badge title center position and draw title
        final float badgeHalfHeight = mBadgeBounds.height() * 0.5F;
        float badgeVerticalOffset = (mBgBadgeBounds.height() * 0.5F) + badgeHalfHeight - mBadgeBounds.bottom
                + modelBadgeOffset;
        canvas.drawText(model.getBadgeTitle(), badgeBoundsHorizontalOffset,
                badgeVerticalOffset + mBadgeBounds.height() - (mBadgeBounds.height() * model.mBadgeFraction),
                mBadgePaint);
    }
}

From source file:com.simon.dribbble.widget.navigationbar.NavigationTabBar.java

@SuppressWarnings("ConstantConditions")
@Override//from w w  w  .  j  av a2 s .  c  o  m
protected void onDraw(final Canvas canvas) {
    // Get height of NTB with badge on nor
    final int mBadgedHeight = (int) (mBounds.height() + mBadgeMargin);

    // Set home canvas
    if (mBitmap == null || mBitmap.isRecycled()) {
        mBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmap);
    }
    // Set pointer canvas
    if (mPointerBitmap == null || mPointerBitmap.isRecycled()) {
        mPointerBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mPointerCanvas.setBitmap(mPointerBitmap);
    }
    // Set icons canvas
    if (mIconsBitmap == null || mIconsBitmap.isRecycled()) {
        mIconsBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mIconsCanvas.setBitmap(mIconsBitmap);
    }
    // Set titles canvas
    if (mIsTitled) {
        if (mTitlesBitmap == null || mTitlesBitmap.isRecycled()) {
            mTitlesBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
            mTitlesCanvas.setBitmap(mTitlesBitmap);
        }
    } else
        mTitlesBitmap = null;

    // Reset and clear canvases
    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mPointerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    if (mIsTitled)
        mTitlesCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

    if (mCornersRadius == 0)
        canvas.drawRect(mBgBounds, mBgPaint);
    else
        canvas.drawRoundRect(mBgBounds, mCornersRadius, mCornersRadius, mBgPaint);

    // Get pointer badge margin for gravity
    final float barBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;

    // Draw our model colors
    for (int i = 0; i < mModels.size(); i++) {
        mPaint.setColor(mModels.get(i).getColor());

        if (mIsHorizontalOrientation) {
            final float left = mModelSize * i;
            final float right = left + mModelSize;
            mCanvas.drawRect(left, barBadgeMargin, right, mBounds.height() + barBadgeMargin, mPaint);
        } else {
            final float top = mModelSize * i;
            final float bottom = top + mModelSize;
            mCanvas.drawRect(0.0F, top, mBounds.width(), bottom, mPaint);
        }
    }

    // Set bound of pointer
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, barBadgeMargin, mPointerRightBottom,
                mBounds.height() + barBadgeMargin);
    else
        mPointerBounds.set(0.0F, mPointerLeftTop, mBounds.width(), mPointerRightBottom);

    // Draw pointer for model colors
    if (mCornersRadius == 0)
        mPointerCanvas.drawRect(mPointerBounds, mPaint);
    else
        mPointerCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mPaint);

    // Draw pointer into home canvas
    mCanvas.drawBitmap(mPointerBitmap, 0.0F, 0.0F, mPointerPaint);

    // Set vars for icon when model with title or without
    final float iconMarginTitleHeight = mIconSize + mTitleMargin + mModelTitleSize;

    // Draw model icons
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Variables to center our icons
        final float leftOffset;
        final float topOffset;
        final float matrixCenterX;
        final float matrixCenterY;

        // Set offset to titles
        final float leftTitleOffset = (mModelSize * i) + (mModelSize * 0.5F);
        final float topTitleOffset = mBounds.height() - (mBounds.height() - iconMarginTitleHeight) * 0.5F;

        if (mIsHorizontalOrientation) {
            leftOffset = (mModelSize * i) + (mModelSize - model.mIcon.getWidth()) * 0.5F;
            topOffset = (mBounds.height() - model.mIcon.getHeight()) * 0.5F;
        } else {
            leftOffset = (mBounds.width() - (float) model.mIcon.getWidth()) * 0.5F;
            topOffset = (mModelSize * i) + (mModelSize - (float) model.mIcon.getHeight()) * 0.5F;
        }

        matrixCenterX = leftOffset + (float) model.mIcon.getWidth() * 0.5F;
        matrixCenterY = topOffset + (float) model.mIcon.getHeight() * 0.5F;

        // Title translate position
        final float titleTranslate = topOffset - model.mIcon.getHeight() * TITLE_MARGIN_SCALE_FRACTION;

        // Translate icon to model center
        model.mIconMatrix.setTranslate(leftOffset,
                (mIsTitled && mTitleMode == TitleMode.ALL) ? titleTranslate : topOffset);

        // Get interpolated fraction for left last and current models
        final float interpolation = mResizeInterpolator.getResizeInterpolation(mFraction, true);
        final float lastInterpolation = mResizeInterpolator.getResizeInterpolation(mFraction, false);

        // Scale value relative to interpolation
        final float matrixScale = model.mActiveIconScaleBy * (mIsScaled ? interpolation : NON_SCALED_FRACTION);
        final float matrixLastScale = model.mActiveIconScaleBy
                * (mIsScaled ? lastInterpolation : (MAX_FRACTION - NON_SCALED_FRACTION));

        // Get title alpha relative to interpolation
        final int titleAlpha = (int) (MAX_ALPHA * interpolation);
        final int titleLastAlpha = MAX_ALPHA - (int) (MAX_ALPHA * lastInterpolation);
        // Get title scale relative to interpolation
        final float titleScale = MAX_FRACTION
                + ((mIsScaled ? interpolation : NON_SCALED_FRACTION) * TITLE_ACTIVE_SCALE_BY);
        final float titleLastScale = mIsScaled
                ? (MAX_FRACTION + TITLE_ACTIVE_SCALE_BY) - (lastInterpolation * TITLE_ACTIVE_SCALE_BY)
                : titleScale;

        mIconPaint.setAlpha(MAX_ALPHA);
        if (model.mSelectedIcon != null)
            mSelectedIconPaint.setAlpha(MAX_ALPHA);

        // Check if we handle models from touch on NTB or from ViewPager
        // There is a strange logic
        // of ViewPager onPageScrolled method, so it is
        if (mIsSetIndexFromTabBar) {
            if (mIndex == i)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (mLastIndex == i)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        } else {
            if (i == mIndex + 1)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (i == mIndex)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        }

        // Draw original model icon
        if (model.mSelectedIcon == null) {
            if (model.mIcon != null && !model.mIcon.isRecycled())
                mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        } else {
            if (mIconPaint.getAlpha() != MIN_ALPHA && model.mIcon != null && !model.mIcon.isRecycled())
                // Draw original icon when is visible
                mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        }
        // Draw selected icon when exist and visible
        if (mSelectedIconPaint.getAlpha() != MIN_ALPHA && model.mSelectedIcon != null
                && !model.mSelectedIcon.isRecycled())
            mIconsCanvas.drawBitmap(model.mSelectedIcon, model.mIconMatrix, mSelectedIconPaint);

        if (mIsTitled)
            mTitlesCanvas.drawText(isInEditMode() ? PREVIEW_TITLE : model.getTitle(), leftTitleOffset,
                    topTitleOffset, mModelTitlePaint);
    }

    // Reset pointer bounds for icons and titles
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, 0.0F, mPointerRightBottom, mBounds.height());
    if (mCornersRadius == 0) {
        if (mIsTinted)
            mIconsCanvas.drawRect(mPointerBounds, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRect(mPointerBounds, mIconPointerPaint);
    } else {
        if (mIsTinted)
            mIconsCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
    }

    // Draw general bitmap
    canvas.drawBitmap(mBitmap, 0.0F, 0.0F, null);
    // Draw icons bitmap on top
    canvas.drawBitmap(mIconsBitmap, 0.0F, barBadgeMargin, null);
    // Draw titles bitmap on top
    if (mIsTitled)
        canvas.drawBitmap(mTitlesBitmap, 0.0F, barBadgeMargin, null);

    // If is not badged, exit
    if (!mIsBadged)
        return;

    // Model badge margin and offset relative to gravity mode
    final float modelBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : mBounds.height();
    final float modelBadgeOffset = mBadgeGravity == BadgeGravity.TOP ? 0.0F : mBounds.height() - mBadgeMargin;

    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Set preview badge title
        if (isInEditMode() || TextUtils.isEmpty(model.getBadgeTitle()))
            model.setBadgeTitle(PREVIEW_BADGE);

        // Set badge title bounds
        mBadgePaint.setTextSize(mBadgeTitleSize * model.mBadgeFraction);
        mBadgePaint.getTextBounds(model.getBadgeTitle(), 0, model.getBadgeTitle().length(), mBadgeBounds);

        // Get horizontal and vertical padding for bg
        final float horizontalPadding = mBadgeTitleSize * BADGE_HORIZONTAL_FRACTION;
        final float verticalPadding = horizontalPadding * BADGE_VERTICAL_FRACTION;

        // Set horizontal badge offset
        final float badgeBoundsHorizontalOffset = (mModelSize * i)
                + (mModelSize * mBadgePosition.mPositionFraction);

        // If is badge title only one char, so create circle else round rect
        final float badgeMargin = mBadgeMargin * model.mBadgeFraction;
        if (model.getBadgeTitle().length() == 1) {
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - badgeMargin, modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset + badgeMargin, modelBadgeMargin + badgeMargin);
        } else
            mBgBadgeBounds.set(
                    badgeBoundsHorizontalOffset
                            - Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset
                            + Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeOffset + (verticalPadding * 2.0F) + mBadgeBounds.height());

        // Set color and alpha for badge bg
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else
            mBadgePaint.setColor(mBadgeBgColor == AUTO_COLOR ? mActiveColor : mBadgeBgColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set corners to round rect for badge bg and draw
        final float cornerRadius = mBgBadgeBounds.height() * 0.5F;
        canvas.drawRoundRect(mBgBadgeBounds, cornerRadius, cornerRadius, mBadgePaint);

        // Set color and alpha for badge title
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else //noinspection ResourceAsColor
            mBadgePaint.setColor(mBadgeTitleColor == AUTO_COLOR ? model.getColor() : mBadgeTitleColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set badge title center position and draw title
        final float badgeHalfHeight = mBadgeBounds.height() * 0.5F;
        float badgeVerticalOffset = (mBgBadgeBounds.height() * 0.5F) + badgeHalfHeight - mBadgeBounds.bottom
                + modelBadgeOffset;
        canvas.drawText(model.getBadgeTitle(), badgeBoundsHorizontalOffset,
                badgeVerticalOffset + mBadgeBounds.height() - (mBadgeBounds.height() * model.mBadgeFraction),
                mBadgePaint);
    }
}

From source file:devlight.io.library.ntb.NavigationTabBar.java

@SuppressWarnings("ConstantConditions")
@Override//ww  w.  ja  va 2s .c  om
protected void onDraw(final Canvas canvas) {
    // Get height of NTB with badge on nor
    final int mBadgedHeight = (int) (mBounds.height() + mBadgeMargin);

    // Set main canvas
    if (mBitmap == null || mBitmap.isRecycled()) {
        mBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmap);
    }
    // Set pointer canvas
    if (mPointerBitmap == null || mPointerBitmap.isRecycled()) {
        mPointerBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mPointerCanvas.setBitmap(mPointerBitmap);
    }
    // Set icons canvas
    if (mIconsBitmap == null || mIconsBitmap.isRecycled()) {
        mIconsBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
        mIconsCanvas.setBitmap(mIconsBitmap);
    }
    // Set titles canvas
    if (mIsTitled) {
        if (mTitlesBitmap == null || mTitlesBitmap.isRecycled()) {
            mTitlesBitmap = Bitmap.createBitmap((int) mBounds.width(), mBadgedHeight, Bitmap.Config.ARGB_8888);
            mTitlesCanvas.setBitmap(mTitlesBitmap);
        }
    } else
        mTitlesBitmap = null;

    // Reset and clear canvases
    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mPointerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    if (mIsTitled)
        mTitlesCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

    if (mCornersRadius == 0)
        canvas.drawRect(mBgBounds, mBgPaint);
    else
        canvas.drawRoundRect(mBgBounds, mCornersRadius, mCornersRadius, mBgPaint);

    // Get pointer badge margin for gravity
    final float barBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;

    // Draw our model colors
    for (int i = 0; i < mModels.size(); i++) {
        mPaint.setColor(mModels.get(i).getColor());

        if (mIsHorizontalOrientation) {
            final float left = mModelSize * i;
            final float right = left + mModelSize;
            mCanvas.drawRect(left, barBadgeMargin, right, mBounds.height() + barBadgeMargin, mPaint);
        } else {
            final float top = mModelSize * i;
            final float bottom = top + mModelSize;
            mCanvas.drawRect(0.0F, top, mBounds.width(), bottom, mPaint);
        }
    }

    // Set bound of pointer
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, barBadgeMargin, mPointerRightBottom,
                mBounds.height() + barBadgeMargin);
    else
        mPointerBounds.set(0.0F, mPointerLeftTop, mBounds.width(), mPointerRightBottom);

    // Draw pointer for model colors
    if (mCornersRadius == 0)
        mPointerCanvas.drawRect(mPointerBounds, mPaint);
    else
        mPointerCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mPaint);

    // Draw pointer into main canvas
    mCanvas.drawBitmap(mPointerBitmap, 0.0F, 0.0F, mPointerPaint);

    // Set vars for icon when model with title or without
    final float iconMarginTitleHeight = mIconSize + mTitleMargin + mModelTitleSize;

    // Draw model icons
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Variables to center our icons
        final float leftOffset;
        final float topOffset;
        final float matrixCenterX;
        final float matrixCenterY;

        // Set offset to titles
        final float leftTitleOffset;
        final float topTitleOffset;
        if (mIsHorizontalOrientation) {
            leftOffset = (mModelSize * i) + (mModelSize - model.mIcon.getWidth()) * 0.5F;
            topOffset = (mBounds.height() - model.mIcon.getHeight()) * 0.5F;

            // Set offset to titles
            leftTitleOffset = (mModelSize * i) + (mModelSize * 0.5F);
            topTitleOffset = mBounds.height() - (mBounds.height() - iconMarginTitleHeight) * 0.5F;

        } else {
            leftOffset = (mBounds.width() - (float) model.mIcon.getWidth()) * 0.5F;
            topOffset = (mModelSize * i) + (mModelSize - (float) model.mIcon.getHeight()) * 0.5F;

            // Set offset to titles
            leftTitleOffset = leftOffset + (float) model.mIcon.getWidth() * 0.5F;
            topTitleOffset = topOffset + (model.mIcon.getHeight() + iconMarginTitleHeight) * 0.5f;
        }

        matrixCenterX = leftOffset + (float) model.mIcon.getWidth() * 0.5F;
        matrixCenterY = topOffset + (float) model.mIcon.getHeight() * 0.5F;

        // Title translate position
        final float titleTranslate = topOffset - model.mIcon.getHeight() * TITLE_MARGIN_SCALE_FRACTION;

        // Translate icon to model center
        model.mIconMatrix.setTranslate(leftOffset,
                (mIsTitled && mTitleMode == TitleMode.ALL) ? titleTranslate : topOffset);

        // Get interpolated fraction for left last and current models
        final float interpolation = mResizeInterpolator.getResizeInterpolation(mFraction, true);
        final float lastInterpolation = mResizeInterpolator.getResizeInterpolation(mFraction, false);

        // Scale value relative to interpolation
        final float matrixScale = model.mActiveIconScaleBy * interpolation;
        final float matrixLastScale = model.mActiveIconScaleBy * lastInterpolation;

        // Get title alpha relative to interpolation
        final int titleAlpha = (int) (MAX_ALPHA * interpolation);
        final int titleLastAlpha = MAX_ALPHA - (int) (MAX_ALPHA * lastInterpolation);
        // Get title scale relative to interpolation
        final float titleScale = mIsScaled ? MAX_FRACTION + interpolation * TITLE_ACTIVE_SCALE_BY
                : MAX_FRACTION;
        final float titleLastScale = mIsScaled
                ? (MAX_FRACTION + TITLE_ACTIVE_SCALE_BY) - (lastInterpolation * TITLE_ACTIVE_SCALE_BY)
                : titleScale;

        mIconPaint.setAlpha(MAX_ALPHA);
        if (model.mSelectedIcon != null)
            mSelectedIconPaint.setAlpha(MAX_ALPHA);

        // Check if we handle models from touch on NTB or from ViewPager
        // There is a strange logic
        // of ViewPager onPageScrolled method, so it is
        if (mIsSetIndexFromTabBar) {
            if (mIndex == i)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (mLastIndex == i)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        } else {
            if (i == mIndex + 1)
                updateCurrentModel(model, leftOffset, topOffset, titleTranslate, interpolation, matrixCenterX,
                        matrixCenterY, matrixScale, titleScale, titleAlpha);
            else if (i == mIndex)
                updateLastModel(model, leftOffset, topOffset, titleTranslate, lastInterpolation, matrixCenterX,
                        matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha);
            else
                updateInactiveModel(model, leftOffset, topOffset, titleScale, matrixScale, matrixCenterX,
                        matrixCenterY);
        }

        // Draw original model icon
        if (model.mSelectedIcon == null) {
            if (model.mIcon != null && !model.mIcon.isRecycled())
                mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        } else if (mIconPaint.getAlpha() != MIN_ALPHA && model.mIcon != null && !model.mIcon.isRecycled())
            // Draw original icon when is visible
            mIconsCanvas.drawBitmap(model.mIcon, model.mIconMatrix, mIconPaint);
        // Draw selected icon when exist and visible
        if (mSelectedIconPaint.getAlpha() != MIN_ALPHA && model.mSelectedIcon != null
                && !model.mSelectedIcon.isRecycled())
            mIconsCanvas.drawBitmap(model.mSelectedIcon, model.mIconMatrix, mSelectedIconPaint);
        if (mIsTitled)
            mTitlesCanvas.drawText(isInEditMode() ? PREVIEW_TITLE : model.getTitle(), leftTitleOffset,
                    topTitleOffset, mModelTitlePaint);
    }

    // Reset pointer bounds for icons and titles
    if (mIsHorizontalOrientation)
        mPointerBounds.set(mPointerLeftTop, 0.0F, mPointerRightBottom, mBounds.height());
    if (mCornersRadius == 0) {
        if (mIsTinted)
            mIconsCanvas.drawRect(mPointerBounds, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRect(mPointerBounds, mIconPointerPaint);
    } else {
        if (mIsTinted)
            mIconsCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
        if (mIsTitled)
            mTitlesCanvas.drawRoundRect(mPointerBounds, mCornersRadius, mCornersRadius, mIconPointerPaint);
    }

    // Draw general bitmap
    canvas.drawBitmap(mBitmap, 0.0F, 0.0F, null);
    // Draw icons bitmap on top
    canvas.drawBitmap(mIconsBitmap, 0.0F, barBadgeMargin, null);
    // Draw titles bitmap on top
    if (mIsTitled)
        canvas.drawBitmap(mTitlesBitmap, 0.0F, barBadgeMargin, null);

    // If is not badged, exit
    if (!mIsBadged)
        return;

    // Model badge margin and offset relative to gravity mode
    final float modelBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : mBounds.height();
    final float modelBadgeOffset = mBadgeGravity == BadgeGravity.TOP ? 0.0F : mBounds.height() - mBadgeMargin;

    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);

        // Set preview badge title
        if (isInEditMode() || TextUtils.isEmpty(model.getBadgeTitle()))
            model.setBadgeTitle(PREVIEW_BADGE);

        // Set badge title bounds
        mBadgePaint.setTextSize(mBadgeTitleSize * model.mBadgeFraction);
        mBadgePaint.getTextBounds(model.getBadgeTitle(), 0, model.getBadgeTitle().length(), mBadgeBounds);

        // Get horizontal and vertical padding for bg
        final float horizontalPadding = mBadgeTitleSize * BADGE_HORIZONTAL_FRACTION;
        final float verticalPadding = horizontalPadding * BADGE_VERTICAL_FRACTION;

        // Set horizontal badge offset
        final float badgeBoundsHorizontalOffset = (mModelSize * i)
                + (mModelSize * mBadgePosition.mPositionFraction);

        // If is badge title only one char, so create circle else round rect
        final float badgeMargin = mBadgeMargin * model.mBadgeFraction;
        if (model.getBadgeTitle().length() == 1) {
            mBgBadgeBounds.set(badgeBoundsHorizontalOffset - badgeMargin, modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset + badgeMargin, modelBadgeMargin + badgeMargin);
        } else
            mBgBadgeBounds.set(
                    badgeBoundsHorizontalOffset
                            - Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeMargin - badgeMargin,
                    badgeBoundsHorizontalOffset
                            + Math.max(badgeMargin, mBadgeBounds.centerX() + horizontalPadding),
                    modelBadgeOffset + (verticalPadding * 2.0F) + mBadgeBounds.height());

        // Set color and alpha for badge bg
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else
            mBadgePaint.setColor(mBadgeBgColor == AUTO_COLOR ? mActiveColor : mBadgeBgColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set corners to round rect for badge bg and draw
        final float cornerRadius = mBgBadgeBounds.height() * 0.5F;
        canvas.drawRoundRect(mBgBadgeBounds, cornerRadius, cornerRadius, mBadgePaint);

        // Set color and alpha for badge title
        if (model.mBadgeFraction == MIN_FRACTION)
            mBadgePaint.setColor(Color.TRANSPARENT);
        else //noinspection ResourceAsColor
            mBadgePaint.setColor(mBadgeTitleColor == AUTO_COLOR ? model.getColor() : mBadgeTitleColor);
        mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));

        // Set badge title center position and draw title
        final float badgeHalfHeight = mBadgeBounds.height() * 0.5F;
        float badgeVerticalOffset = (mBgBadgeBounds.height() * 0.5F) + badgeHalfHeight - mBadgeBounds.bottom
                + modelBadgeOffset;
        canvas.drawText(model.getBadgeTitle(), badgeBoundsHorizontalOffset,
                badgeVerticalOffset + mBadgeBounds.height() - (mBadgeBounds.height() * model.mBadgeFraction),
                mBadgePaint);
    }
}