Example usage for android.graphics Canvas drawCircle

List of usage examples for android.graphics Canvas drawCircle

Introduction

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

Prototype

public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) 

Source Link

Document

Draw the specified circle using the specified paint.

Usage

From source file:com.chrynan.guitarchords.view.GuitarChordView.java

@Override
protected void onDraw(Canvas canvas) {
    //This method handles a lot of work, possibly too much for an onDraw method, but since I'm not animating
    //or updating the view often, it should be capable of performing the tasks without too much effort.
    //I can optimize this later.

    //First draw the strings and fret markers
    //Fret markers; not worrying about whether or not to show the bridge nut now (since that wasn't calculated
    //in to the drawing size)
    //TODO need to take into account whether or not to show bridgeNut
    int fretCount = chord.getFretCount();
    fretCount = (fretCount < 4) ? 4 : fretCount;
    for (int i = 0; i < fretCount + 1; i++) {
        canvas.drawLine(drawingBounds.left + fretNumberBounds.width(),
                (drawingBounds.top + stringMarkerBounds.height()) + (i * fretSize) + (i * fretMarkerSize),
                drawingBounds.right - stringSize,
                (drawingBounds.top + stringMarkerBounds.height()) + (i * fretSize) + (i * fretMarkerSize),
                fretMarkerPaint);/* w ww . ja v  a2 s . c om*/
    }
    //Strings
    for (int i = 0; i < stringCount; i++) {
        canvas.drawLine((stringMarkerBounds.left) + (i * stringDistance) + (i * stringSize),
                drawingBounds.top + stringMarkerBounds.height(),
                (stringMarkerBounds.left) + (i * stringDistance) + (i * stringSize),
                drawingBounds.bottom - fretMarkerSize, stringPaint);
    }
    //Next draw the fret numbers and string markers
    //Fret numbers; check if we are showing them or not
    if (showFretNumbers) {
        for (int i = 0; i < fretCount; i++) {
            canvas.drawText(String.valueOf(i + 1), drawingBounds.left + fretNumberBounds.width() / 2,
                    getVerticalCenterTextPosition(
                            stringMarkerBounds.bottom + (i * fretMarkerSize) + (i * fretSize) + (fretSize / 2),
                            String.valueOf(i + 1), fretNumberPaint),
                    fretNumberPaint);
        }
    }
    //String markers
    for (int i : chord.getMutedStrings()) {
        canvas.drawText(mutedText,
                (drawingBounds.left + fretNumberBounds.width()) + ((stringCount - i) * stringDistance)
                        + ((stringCount - i) * stringSize),
                getVerticalCenterTextPosition(drawingBounds.top + (stringMarkerBounds.height() / 2), mutedText,
                        stringMarkerPaint),
                stringMarkerPaint);
    }
    for (int i : chord.getOpenStrings()) {
        canvas.drawText(openStringText,
                (drawingBounds.left + fretNumberBounds.width()) + ((stringCount - i) * stringDistance)
                        + ((stringCount - i) * stringSize),
                getVerticalCenterTextPosition(drawingBounds.top + (stringMarkerBounds.height() / 2),
                        openStringText, stringMarkerPaint),
                stringMarkerPaint);
    }
    //Finally, draw all the notes and the note text
    //Bars
    float startCenterX;
    float startCenterY;
    for (ChordMarker cm : chord.getBars()) {
        startCenterX = (drawingBounds.left + fretNumberBounds.width())
                + ((stringCount - cm.getStartString()) * stringDistance)
                + ((stringCount - cm.getStartString()) * stringSize);
        startCenterY = stringMarkerBounds.bottom
                + (((cm.getFret() * fretSize) + (cm.getFret() * fretMarkerSize)) - (fretSize / 2));
        float endCenterX = (drawingBounds.left + fretNumberBounds.width())
                + ((stringCount - cm.getEndString()) * stringDistance)
                + ((stringCount - cm.getEndString()) * stringSize);
        float endCenterY = startCenterY;
        canvas.drawCircle(startCenterX, startCenterY, noteSize / 2, notePaint);
        canvas.drawCircle(endCenterX, endCenterY, noteSize / 2, notePaint);
        if (showFingerNumbers) {
            canvas.drawText(String.valueOf(cm.getFinger()), startCenterX, getVerticalCenterTextPosition(
                    startCenterY, String.valueOf(cm.getFinger()), noteNumberPaint), noteNumberPaint);
            canvas.drawText(String.valueOf(cm.getFinger()), endCenterX,
                    getVerticalCenterTextPosition(endCenterY, String.valueOf(cm.getFinger()), noteNumberPaint),
                    noteNumberPaint);
        }
        barLinePath = new Path();
        barLinePath.moveTo(startCenterX, startCenterY - (noteSize / 2));
        barLinePath.quadTo((startCenterX + endCenterX) / 2, (startCenterY + endCenterY - (noteSize / 2)) / 4,
                endCenterX, endCenterY - (noteSize / 2));
        canvas.drawPath(barLinePath, barLinePaint);
    }
    //Individual notes
    for (ChordMarker cm : chord.getIndividualNotes()) {
        startCenterX = (drawingBounds.left + fretNumberBounds.width())
                + ((stringCount - cm.getStartString()) * stringDistance)
                + ((stringCount - cm.getStartString()) * stringSize);
        startCenterY = stringMarkerBounds.bottom
                + (((cm.getFret() * fretSize) + (cm.getFret() * fretMarkerSize)) - (fretSize / 2));
        canvas.drawCircle(startCenterX, startCenterY, noteSize / 2, notePaint);
        if (showFingerNumbers) {
            canvas.drawText(String.valueOf(cm.getFinger()), startCenterX, getVerticalCenterTextPosition(
                    startCenterY, String.valueOf(cm.getFinger()), noteNumberPaint), noteNumberPaint);
        }
    }
}

From source file:com.hxsn.witwork.ui.ViewfinderView.java

@Override
public void onDraw(Canvas canvas) {
    // ??????CameraManager?
    if (CameraManager.get() == null) {
        return;/* w ww. j  a  va2  s . c o  m*/
    }
    Rect frame = CameraManager.get().getFramingRect();
    if (frame == null) {
        return;
    }

    // ?
    if (!isFirst) {
        isFirst = true;
        slideTop = frame.top;
        slideBottom = frame.bottom;
    }

    // ??
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    paint.setColor(resultBitmap != null ? resultColor : maskColor);

    // ?????????????
    // ?????????
    canvas.drawRect(0, 0, width, frame.top + 15, paint);
    canvas.drawRect(0, frame.top + 15, frame.left + 15, frame.bottom - 14, paint);
    canvas.drawRect(frame.right - 14, frame.top + 15, width, frame.bottom - 14, paint);
    canvas.drawRect(0, frame.bottom - 14, width, height, paint);

    if (resultBitmap != null) {
        // Draw the opaque result bitmap over the scanning rectangle
        paint.setAlpha(OPAQUE);
        canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
    } else {

        // ??8
        paint.setColor(Color.rgb(139, 193, 17));
        canvas.drawRect(frame.left, frame.top, frame.left + ScreenRate, frame.top + CORNER_WIDTH, paint);
        canvas.drawRect(frame.left, frame.top, frame.left + CORNER_WIDTH, frame.top + ScreenRate, paint);
        canvas.drawRect(frame.right - ScreenRate, frame.top, frame.right, frame.top + CORNER_WIDTH, paint);
        canvas.drawRect(frame.right - CORNER_WIDTH, frame.top, frame.right, frame.top + ScreenRate, paint);
        canvas.drawRect(frame.left, frame.bottom - CORNER_WIDTH, frame.left + ScreenRate, frame.bottom, paint);
        canvas.drawRect(frame.left, frame.bottom - ScreenRate, frame.left + CORNER_WIDTH, frame.bottom, paint);
        canvas.drawRect(frame.right - ScreenRate, frame.bottom - CORNER_WIDTH, frame.right, frame.bottom,
                paint);
        canvas.drawRect(frame.right - CORNER_WIDTH, frame.bottom - ScreenRate, frame.right, frame.bottom,
                paint);

        // ,??SPEEN_DISTANCE
        slideTop += SPEEN_DISTANCE;
        if (slideTop >= frame.bottom) {
            slideTop = frame.top;
        }
        // canvas.drawRect(frame.left + MIDDLE_LINE_PADDING, slideTop -
        // MIDDLE_LINE_WIDTH/2, frame.right - MIDDLE_LINE_PADDING,slideTop +
        // MIDDLE_LINE_WIDTH/2, paint);
        Rect lineRect = new Rect();

        lineRect.left = frame.left;
        lineRect.right = frame.right;
        lineRect.top = slideTop;
        lineRect.bottom = slideTop + 18;
        canvas.drawBitmap(((BitmapDrawable) (getResources().getDrawable(R.drawable.fgx))).getBitmap(), null,
                lineRect, paint);

        // ???
        paint.setColor(Color.WHITE);
        paint.setTextSize(TEXT_SIZE * density);
        // paint.setAlpha(0x40);
        // paint.setTypeface(Typeface.create("System", Typeface.BOLD));

        canvas.drawText("?/??????", frame.left,
                (float) (frame.bottom + (float) TEXT_PADDING_TOP * density), paint);
        canvas.drawText("??" + num + "", frame.left,
                (float) (frame.bottom + (float) TEXT_PADDING_TOP * density + 50), paint);

        int max = 7;
        if (name.size() < max) {
            max = name.size();
            for (int i = 0; i < max; i++) {
                canvas.drawText(name.get(i), frame.left,
                        (float) (frame.bottom + (float) TEXT_PADDING_TOP * density + 100 + 50 * i), paint);
            }
        } else {
            for (int i = 6; i >= 0; i--) {
                canvas.drawText(name.get((name.size() - 1) - (6 - i)), frame.left,
                        (float) (frame.bottom + (float) TEXT_PADDING_TOP * density + 100 + 50 * i), paint);
            }
        }

        paint.setStyle(Style.STROKE);
        canvas.drawRect(frame.left + 15, frame.top + 15, frame.right - 15, frame.bottom - 15, paint);
        setViewY(frame.bottom);
        paint.setStyle(Style.FILL);

        Collection<ResultPoint> currentPossible = possibleResultPoints;
        Collection<ResultPoint> currentLast = lastPossibleResultPoints;
        if (currentPossible.isEmpty()) {
            lastPossibleResultPoints = null;
        } else {
            possibleResultPoints = new HashSet<ResultPoint>(5);
            lastPossibleResultPoints = currentPossible;
            paint.setAlpha(OPAQUE);
            paint.setColor(resultPointColor);
            for (ResultPoint point : currentPossible) {
                canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint);
            }
        }
        if (currentLast != null) {
            paint.setAlpha(OPAQUE / 2);
            paint.setColor(resultPointColor);
            for (ResultPoint point : currentLast) {
                canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint);
            }
        }

        // ????
        postInvalidate();
        // postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top,
        // frame.right, frame.bottom);

    }
}

From source file:com.focustech.common.widget.TitlePageIndicator.java

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mViewPager == null) {
        return;/*from   ww  w.ja v a2s. c  om*/
    }
    final int count = mViewPager.getAdapter().getCount();
    if (count == 0) {
        return;
    }

    // mCurrentPage is -1 on first start and after orientation changed. If
    // so, retrieve the correct index from
    // viewpager.
    if (mCurrentPage == -1 && mViewPager != null) {
        mCurrentPage = mViewPager.getCurrentItem();
    }

    // Calculate views bounds
    ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
    final int boundsSize = bounds.size();

    // Make sure we're on a page that still exists
    if (mCurrentPage >= boundsSize) {
        setCurrentItem(boundsSize - 1);
        return;
    }

    final int countMinusOne = count - 1;
    final float halfWidth = getWidth() / 2f;
    final int left = getLeft();
    final float leftClip = left + mClipPadding;
    final int width = getWidth();
    int height = getHeight();
    final int right = left + width;
    final float rightClip = right - mClipPadding;

    int page = mCurrentPage;
    float offsetPercent;
    if (mPageOffset <= 0.5) {
        offsetPercent = mPageOffset;
    } else {
        page += 1;
        offsetPercent = 1 - mPageOffset;
    }
    final boolean currentSelected = (offsetPercent <= SELECTION_FADE_PERCENTAGE);
    final boolean currentBold = (offsetPercent <= BOLD_FADE_PERCENTAGE);
    final float selectedPercent = (SELECTION_FADE_PERCENTAGE - offsetPercent) / SELECTION_FADE_PERCENTAGE;

    // Verify if the current view must be clipped to the screen
    Rect curPageBound = bounds.get(mCurrentPage);
    float curPageWidth = curPageBound.right - curPageBound.left;
    if (curPageBound.left < leftClip) {
        // Try to clip to the screen (left side)
        clipViewOnTheLeft(curPageBound, curPageWidth, left);
    }
    if (curPageBound.right > rightClip) {
        // Try to clip to the screen (right side)
        clipViewOnTheRight(curPageBound, curPageWidth, right);
    }

    // Left views starting from the current position
    if (mCurrentPage > 0) {
        for (int i = mCurrentPage - 1; i >= 0; i--) {
            Rect bound = bounds.get(i);
            // Is left side is outside the screen
            if (bound.left < leftClip) {
                int w = bound.right - bound.left;
                // Try to clip to the screen (left side)
                clipViewOnTheLeft(bound, w, left);
                // Except if there's an intersection with the right view
                Rect rightBound = bounds.get(i + 1);
                // Intersection
                if (bound.right + mTitlePadding > rightBound.left) {
                    bound.left = (int) (rightBound.left - w - mTitlePadding);
                    bound.right = bound.left + w;
                }
            }
        }
    }
    // Right views starting from the current position
    if (mCurrentPage < countMinusOne) {
        for (int i = mCurrentPage + 1; i < count; i++) {
            Rect bound = bounds.get(i);
            // If right side is outside the screen
            if (bound.right > rightClip) {
                int w = bound.right - bound.left;
                // Try to clip to the screen (right side)
                clipViewOnTheRight(bound, w, right);
                // Except if there's an intersection with the left view
                Rect leftBound = bounds.get(i - 1);
                // Intersection
                if (bound.left - mTitlePadding < leftBound.right) {
                    bound.left = (int) (leftBound.right + mTitlePadding);
                    bound.right = bound.left + w;
                }
            }
        }
    }

    // Now draw views
    int colorTextAlpha = mColorText >>> 24;
    for (int i = 0; i < count; i++) {
        // Get the title
        Rect bound = bounds.get(i);
        // Only if one side is visible
        if ((bound.left > left && bound.left < right) || (bound.right > left && bound.right < right)) {
            final boolean currentPage = (i == page);
            final CharSequence pageTitle = getTitle(i);

            // Only set bold if we are within bounds
            mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText);

            // Draw text as unselected
            mPaintText.setColor(mColorText);
            if (currentPage && currentSelected) {
                // Fade out/in unselected text as the selected text fades
                // in/out
                mPaintText.setAlpha(colorTextAlpha - (int) (colorTextAlpha * selectedPercent));
            }

            // Except if there's an intersection with the right view
            if (i < boundsSize - 1) {
                Rect rightBound = bounds.get(i + 1);
                // Intersection
                if (bound.right + mTitlePadding > rightBound.left) {
                    int w = bound.right - bound.left;
                    bound.left = (int) (rightBound.left - w - mTitlePadding);
                    bound.right = bound.left + w;
                }
            }

            canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding,
                    mPaintText);

            if (i == 0 && mIsShowPoint) {
                canvas.drawCircle(bound.right - 5, bound.top + (bound.bottom - bound.top) / 3 + mTopPadding, 5,
                        mPaintCircle);
            }

            // If we are within the selected bounds draw the selected text
            if (currentPage && currentSelected) {
                mPaintText.setColor(mColorSelected);
                mPaintText.setAlpha((int) ((mColorSelected >>> 24) * selectedPercent));
                canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding,
                        mPaintText);
            }
        }
    }

    // If we want the line on the top change height to zero and invert the
    // line height to trick the drawing code
    float footerLineHeight = mFooterLineHeight;
    float footerIndicatorLineHeight = mFooterIndicatorHeight;
    if (mLinePosition == LinePosition.Top) {
        height = 0;
        footerLineHeight = -footerLineHeight;
        footerIndicatorLineHeight = -footerIndicatorLineHeight;
    }

    // Draw the footer line
    mPath.reset();
    mPath.moveTo(0, height - footerLineHeight / 2f);
    mPath.lineTo(width, height - footerLineHeight / 2f);
    mPath.close();
    canvas.drawPath(mPath, mPaintFooterLine);

    float heightMinusLine = height - footerLineHeight;
    switch (mFooterIndicatorStyle) {
    case Triangle:
        mPath.reset();
        mPath.moveTo(halfWidth, heightMinusLine - footerIndicatorLineHeight);
        mPath.lineTo(halfWidth + footerIndicatorLineHeight, heightMinusLine);
        mPath.lineTo(halfWidth - footerIndicatorLineHeight, heightMinusLine);
        mPath.close();
        canvas.drawPath(mPath, mPaintFooterIndicator);
        break;

    case Underline:
        if (!currentSelected || page >= boundsSize) {
            break;
        }

        Rect underlineBounds = bounds.get(page);
        final float rightPlusPadding = underlineBounds.right + mFooterIndicatorUnderlinePadding;
        final float leftMinusPadding = underlineBounds.left - mFooterIndicatorUnderlinePadding;
        final float heightMinusLineMinusIndicator = heightMinusLine - footerIndicatorLineHeight;

        mPath.reset();
        mPath.moveTo(leftMinusPadding, heightMinusLine);
        mPath.lineTo(rightPlusPadding, heightMinusLine);
        mPath.lineTo(rightPlusPadding, heightMinusLineMinusIndicator);
        mPath.lineTo(leftMinusPadding, heightMinusLineMinusIndicator);
        mPath.close();

        mPaintFooterIndicator.setAlpha((int) (0xFF * selectedPercent));
        canvas.drawPath(mPath, mPaintFooterIndicator);
        mPaintFooterIndicator.setAlpha(0xFF);
        break;
    default:
        break;
    }
}

From source file:xiaofan.llongimageview.view.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.
 *//*from   w  ww.j a v  a  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 || decoder == null || getWidth() == 0 || getHeight() == 0) {
        return;
    }

    // On first render with no tile map ready, initialise it and kick off async base image loading.
    if (tileMap == null) {
        initialiseBaseLayer(getMaxBitmapDimensions(canvas));
        return;
    }

    // If waiting to translate to new center position, set translate now
    if (sPendingCenter != null && pendingScale != null) {
        scale = pendingScale;
        vTranslate.x = (getWidth() / 2) - (scale * sPendingCenter.x);
        vTranslate.y = (getHeight() / 2) - (scale * sPendingCenter.y);
        sPendingCenter = null;
        pendingScale = null;
        fitToBounds(true);
        refreshRequiredTiles(true);
    }

    // On first display of base image set up position, and in other cases make sure scale is correct.
    fitToBounds(false);

    // Everything is set up and coordinates are valid. Inform subclasses.
    if (!readySent) {
        readySent = true;
        new Thread(new Runnable() {
            public void run() {
                onImageReady();
            }
        }).start();
    }

    // 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);
        scale = 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
        PointF vFocus = sourceToViewCoord(anim.sCenterEnd);
        vTranslate.x -= vFocus.x - vFocusNowX;
        vTranslate.y -= vFocus.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) {
            anim = null;
        }
        invalidate();
    }

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

    // 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()) {
                Rect vRect = convertRect(sourceToViewRect(tile.sRect));
                if (!tile.loading && tile.bitmap != null) {
                    canvas.drawBitmap(tile.bitmap, null, vRect, bitmapPaint);
                    if (debug) {
                        canvas.drawRect(vRect, debugPaint);
                    }
                } else if (tile.loading && debug) {
                    canvas.drawText("LOADING", vRect.left + 5, 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,
                            vRect.left + 5, 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);
        }
    }
}

From source file:com.bizcom.vc.widget.cus.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  w  w.  j  av a 2s  .  co  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 || decoder == null || getWidth() == 0 || getHeight() == 0) {
        return;
    }

    // On first render with no tile map ready, initialise it and kick off
    // async base image loading.
    if (tileMap == null) {
        initialiseBaseLayer(getMaxBitmapDimensions(canvas));
        return;
    }

    // If waiting to translate to new center position, set translate now
    if (sPendingCenter != null && pendingScale != null) {
        scale = pendingScale;
        vTranslate.x = (getWidth() / 2) - (scale * sPendingCenter.x);
        vTranslate.y = (getHeight() / 2) - (scale * sPendingCenter.y);
        sPendingCenter = null;
        pendingScale = null;
        fitToBounds(true);
        refreshRequiredTiles(true);
    }

    // On first display of base image set up position, and in other cases
    // make sure scale is correct.
    fitToBounds(false);

    // Everything is set up and coordinates are valid. Inform subclasses.
    if (!readySent) {
        readySent = true;
        new Thread(new Runnable() {
            public void run() {
                onImageReady();
            }
        }).start();
    }

    // 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);
        scale = 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
        PointF vFocus = sourceToViewCoord(anim.sCenterEnd);
        vTranslate.x -= vFocus.x - vFocusNowX;
        vTranslate.y -= vFocus.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) {
            anim = null;
        }
        invalidate();
    }

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

    // 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()) {
                Rect vRect = convertRect(sourceToViewRect(tile.sRect));
                if (!tile.loading && tile.bitmap != null) {
                    canvas.drawBitmap(tile.bitmap, null, vRect, bitmapPaint);
                    if (debug) {
                        canvas.drawRect(vRect, debugPaint);
                    }
                } else if (tile.loading && debug) {
                    canvas.drawText("LOADING", vRect.left + 5, 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,
                            vRect.left + 5, 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);
        }
    }
}

From source file:com.jjoe64.graphview.series.LineGraphSeries.java

/**
 * plots the series/*w  w  w . ja v a2 s . co  m*/
 * draws the line and the background
 *
 * @param graphView graphview
 * @param canvas canvas
 * @param isSecondScale flag if it is the second scale
 */
@Override
public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) {
    resetDataPoints();

    // get data
    double maxX = graphView.getViewport().getMaxX(false);
    double minX = graphView.getViewport().getMinX(false);

    double maxY;
    double minY;
    if (isSecondScale) {
        maxY = graphView.getSecondScale().getMaxY(false);
        minY = graphView.getSecondScale().getMinY(false);
    } else {
        maxY = graphView.getViewport().getMaxY(false);
        minY = graphView.getViewport().getMinY(false);
    }

    Iterator<E> values = getValues(minX, maxX);

    // draw background
    double lastEndY = 0;
    double lastEndX = 0;

    // draw data
    mPaint.setStrokeWidth(mStyles.thickness);
    mPaint.setColor(getColor());
    mPaintBackground.setColor(mStyles.backgroundColor);

    Paint paint;
    if (mCustomPaint != null) {
        paint = mCustomPaint;
    } else {
        paint = mPaint;
    }

    mPath.reset();

    if (mStyles.drawBackground) {
        mPathBackground.reset();
    }

    double diffY = maxY - minY;
    double diffX = maxX - minX;

    float graphHeight = graphView.getGraphContentHeight();
    float graphWidth = graphView.getGraphContentWidth();
    float graphLeft = graphView.getGraphContentLeft();
    float graphTop = graphView.getGraphContentTop();

    lastEndY = 0;
    lastEndX = 0;

    // needed to end the path for background
    double lastUsedEndX = 0;
    double lastUsedEndY = 0;
    float firstX = -1;
    float firstY = -1;
    float lastRenderedX = Float.NaN;
    int i = 0;
    float lastAnimationReferenceX = graphLeft;

    boolean sameXSkip = false;
    float minYOnSameX = 0f;
    float maxYOnSameX = 0f;

    while (values.hasNext()) {
        E value = values.next();

        double valY = value.getY() - minY;
        double ratY = valY / diffY;
        double y = graphHeight * ratY;

        double valueX = value.getX();
        double valX = valueX - minX;
        double ratX = valX / diffX;
        double x = graphWidth * ratX;

        double orgX = x;
        double orgY = y;

        if (i > 0) {
            // overdraw
            boolean isOverdrawY = false;
            boolean isOverdrawEndPoint = false;
            boolean skipDraw = false;

            if (x > graphWidth) { // end right
                double b = ((graphWidth - lastEndX) * (y - lastEndY) / (x - lastEndX));
                y = lastEndY + b;
                x = graphWidth;
                isOverdrawEndPoint = true;
            }
            if (y < 0) { // end bottom
                // skip when previous and this point is out of bound
                if (lastEndY < 0) {
                    skipDraw = true;
                } else {
                    double b = ((0 - lastEndY) * (x - lastEndX) / (y - lastEndY));
                    x = lastEndX + b;
                }
                y = 0;
                isOverdrawY = isOverdrawEndPoint = true;
            }
            if (y > graphHeight) { // end top
                // skip when previous and this point is out of bound
                if (lastEndY > graphHeight) {
                    skipDraw = true;
                } else {
                    double b = ((graphHeight - lastEndY) * (x - lastEndX) / (y - lastEndY));
                    x = lastEndX + b;
                }
                y = graphHeight;
                isOverdrawY = isOverdrawEndPoint = true;
            }
            if (lastEndX < 0) { // start left
                double b = ((0 - x) * (y - lastEndY) / (lastEndX - x));
                lastEndY = y - b;
                lastEndX = 0;
            }

            // we need to save the X before it will be corrected when overdraw y
            float orgStartX = (float) lastEndX + (graphLeft + 1);

            if (lastEndY < 0) { // start bottom
                if (!skipDraw) {
                    double b = ((0 - y) * (x - lastEndX) / (lastEndY - y));
                    lastEndX = x - b;
                }
                lastEndY = 0;
                isOverdrawY = true;
            }
            if (lastEndY > graphHeight) { // start top
                // skip when previous and this point is out of bound
                if (!skipDraw) {
                    double b = ((graphHeight - y) * (x - lastEndX) / (lastEndY - y));
                    lastEndX = x - b;
                }
                lastEndY = graphHeight;
                isOverdrawY = true;
            }

            float startX = (float) lastEndX + (graphLeft + 1);
            float startY = (float) (graphTop - lastEndY) + graphHeight;
            float endX = (float) x + (graphLeft + 1);
            float endY = (float) (graphTop - y) + graphHeight;
            float startXAnimated = startX;
            float endXAnimated = endX;

            if (endX < startX) {
                // dont draw from right to left
                skipDraw = true;
            }

            // NaN can happen when previous and current value is out of y bounds
            if (!skipDraw && !Float.isNaN(startY) && !Float.isNaN(endY)) {
                // animation
                if (mAnimated) {
                    if ((Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) {
                        long currentTime = System.currentTimeMillis();
                        if (mAnimationStart == 0) {
                            // start animation
                            mAnimationStart = currentTime;
                            mAnimationStartFrameNo = 0;
                        } else {
                            // anti-lag: wait a few frames
                            if (mAnimationStartFrameNo < 15) {
                                // second time
                                mAnimationStart = currentTime;
                                mAnimationStartFrameNo++;
                            }
                        }
                        float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION;
                        float factor = mAnimationInterpolator.getInterpolation(timeFactor);
                        if (timeFactor <= 1.0) {
                            startXAnimated = (startX - lastAnimationReferenceX) * factor
                                    + lastAnimationReferenceX;
                            startXAnimated = Math.max(startXAnimated, lastAnimationReferenceX);
                            endXAnimated = (endX - lastAnimationReferenceX) * factor + lastAnimationReferenceX;
                            ViewCompat.postInvalidateOnAnimation(graphView);
                        } else {
                            // animation finished
                            mLastAnimatedValue = valueX;
                        }
                    } else {
                        lastAnimationReferenceX = endX;
                    }
                }

                // draw data point
                if (!isOverdrawEndPoint) {
                    if (mStyles.drawDataPoints) {
                        // draw first datapoint
                        Paint.Style prevStyle = paint.getStyle();
                        paint.setStyle(Paint.Style.FILL);
                        canvas.drawCircle(endXAnimated, endY, mStyles.dataPointsRadius, paint);
                        paint.setStyle(prevStyle);
                    }
                    registerDataPoint(endX, endY, value);
                }

                if (mDrawAsPath) {
                    mPath.moveTo(startXAnimated, startY);
                }
                // performance opt.
                if (Float.isNaN(lastRenderedX) || Math.abs(endX - lastRenderedX) > .3f) {
                    if (mDrawAsPath) {
                        mPath.lineTo(endXAnimated, endY);
                    } else {
                        // render vertical lines that were skipped
                        if (sameXSkip) {
                            sameXSkip = false;
                            renderLine(canvas,
                                    new float[] { lastRenderedX, minYOnSameX, lastRenderedX, maxYOnSameX },
                                    paint);
                        }
                        renderLine(canvas, new float[] { startXAnimated, startY, endXAnimated, endY }, paint);
                    }
                    lastRenderedX = endX;
                } else {
                    // rendering on same x position
                    // save min+max y position and render it as line
                    if (sameXSkip) {
                        minYOnSameX = Math.min(minYOnSameX, endY);
                        maxYOnSameX = Math.max(maxYOnSameX, endY);
                    } else {
                        // first
                        sameXSkip = true;
                        minYOnSameX = Math.min(startY, endY);
                        maxYOnSameX = Math.max(startY, endY);
                    }
                }

            }

            if (mStyles.drawBackground) {
                if (isOverdrawY) {
                    // start draw original x
                    if (firstX == -1) {
                        firstX = orgStartX;
                        firstY = startY;
                        mPathBackground.moveTo(orgStartX, startY);
                    }
                    // from original start to new start
                    mPathBackground.lineTo(startXAnimated, startY);
                }
                if (firstX == -1) {
                    firstX = startXAnimated;
                    firstY = startY;
                    mPathBackground.moveTo(startXAnimated, startY);
                }
                mPathBackground.lineTo(startXAnimated, startY);
                mPathBackground.lineTo(endXAnimated, endY);
            }

            lastUsedEndX = endXAnimated;
            lastUsedEndY = endY;
        } else if (mStyles.drawDataPoints) {
            //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above)
            float first_X = (float) x + (graphLeft + 1);
            float first_Y = (float) (graphTop - y) + graphHeight;

            if (first_X >= graphLeft && first_Y <= (graphTop + graphHeight)) {
                if (mAnimated && (Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) {
                    long currentTime = System.currentTimeMillis();
                    if (mAnimationStart == 0) {
                        // start animation
                        mAnimationStart = currentTime;
                    }
                    float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION;
                    float factor = mAnimationInterpolator.getInterpolation(timeFactor);
                    if (timeFactor <= 1.0) {
                        first_X = (first_X - lastAnimationReferenceX) * factor + lastAnimationReferenceX;
                        ViewCompat.postInvalidateOnAnimation(graphView);
                    } else {
                        // animation finished
                        mLastAnimatedValue = valueX;
                    }
                }

                Paint.Style prevStyle = paint.getStyle();
                paint.setStyle(Paint.Style.FILL);
                canvas.drawCircle(first_X, first_Y, mStyles.dataPointsRadius, paint);
                paint.setStyle(prevStyle);
            }
        }
        lastEndY = orgY;
        lastEndX = orgX;
        i++;
    }

    if (mDrawAsPath) {
        // draw at the end
        canvas.drawPath(mPath, paint);
    }

    if (mStyles.drawBackground && firstX != -1) {
        // end / close path
        if (lastUsedEndY != graphHeight + graphTop) {
            // dont draw line to same point, otherwise the path is completely broken
            mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop);
        }
        mPathBackground.lineTo(firstX, graphHeight + graphTop);
        if (firstY != graphHeight + graphTop) {
            // dont draw line to same point, otherwise the path is completely broken
            mPathBackground.lineTo(firstX, firstY);
        }
        //mPathBackground.close();
        canvas.drawPath(mPathBackground, mPaintBackground);
    }
}

From source file:p5e610.graphview.series.LineGraphSeries.java

/**
 * plots the series//from  ww w  . j  av a2 s .c o  m
 * draws the line and the background
 *
 * @param graphView graphview
 * @param canvas canvas
 * @param isSecondScale flag if it is the second scale
 */
@Override
public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) {
    resetDataPoints();

    // get data
    double maxY = Double.NEGATIVE_INFINITY;
    double maxX = Double.NEGATIVE_INFINITY;
    double minY = Double.POSITIVE_INFINITY;
    double minX = Double.POSITIVE_INFINITY;

    boolean minXSet = graphView.getViewport().getMinX(false) != null;
    boolean maxXSet = graphView.getViewport().getMaxX(false) != null;
    boolean minYSet = graphView.getViewport().getMinY(false) != null;
    boolean maxYSet = graphView.getViewport().getMaxY(false) != null;

    if (minXSet)
        minX = graphView.getViewport().getMinX(false);
    if (maxXSet) {
        maxX = graphView.getViewport().getMaxX(false);
    }
    if (minYSet) {
        minY = graphView.getViewport().getMinY(false);
    }
    if (maxYSet) {
        maxY = graphView.getViewport().getMaxY(false);
    }

    for (E val : mData) {
        double currX = val.getX();
        double currY = val.getY();

        if (currX > maxX && !maxXSet)
            maxX = currX;
        if (currY > maxY && !maxYSet)
            maxY = currY;
        if (currX < minX && !minXSet)
            minX = currX;
        if (currY < minY && !minYSet)
            minY = currY;
    }

    Iterator<E> values = getValues(minX, maxX);

    // draw background
    double lastEndY = 0;
    double lastEndX = 0;

    // draw data
    mPaint.setStrokeWidth(mStyles.thickness);
    mPaint.setColor(getColor());
    mPaintBackground.setColor(mStyles.backgroundColor);

    Paint paint;
    if (mCustomPaint != null) {
        paint = mCustomPaint;
    } else {
        paint = mPaint;
    }

    mPath.reset();

    if (mStyles.drawBackground) {
        mPathBackground.reset();
    }

    double diffY = maxY - minY;
    double diffX = maxX - minX;

    float graphHeight = graphView.getGraphContentHeight();
    float graphWidth = graphView.getGraphContentWidth();
    float graphLeft = graphView.getGraphContentLeft();
    float graphTop = graphView.getGraphContentTop();

    lastEndY = 0;
    lastEndX = 0;

    // needed to end the path for background
    double lastUsedEndX = 0;
    double lastUsedEndY = 0;
    float firstX = -1;
    float firstY = -1;
    float lastRenderedX = Float.NaN;
    int i = 0;
    float lastAnimationReferenceX = graphLeft;

    boolean sameXSkip = false;
    float minYOnSameX = 0f;
    float maxYOnSameX = 0f;

    while (values.hasNext()) {
        E value = values.next();

        double valY = value.getY() - minY;
        double ratY = valY / diffY;
        double y = graphHeight * ratY;

        double valueX = value.getX();
        double valX = valueX - minX;
        double ratX = valX / diffX;
        double x = graphWidth * ratX;

        double orgX = x;
        double orgY = y;

        if (i > 0) {
            // overdraw
            boolean isOverdrawY = false;
            boolean isOverdrawEndPoint = false;
            boolean skipDraw = false;

            if (x > graphWidth) { // end right
                double b = ((graphWidth - lastEndX) * (y - lastEndY) / (x - lastEndX));
                y = lastEndY + b;
                x = graphWidth;
                isOverdrawEndPoint = true;
            }
            if (y < 0) { // end bottom
                // skip when previous and this point is out of bound
                if (lastEndY < 0) {
                    skipDraw = true;
                } else {
                    double b = ((0 - lastEndY) * (x - lastEndX) / (y - lastEndY));
                    x = lastEndX + b;
                }
                y = 0;
                isOverdrawY = isOverdrawEndPoint = true;
            }
            if (y > graphHeight) { // end top
                // skip when previous and this point is out of bound
                if (lastEndY > graphHeight) {
                    skipDraw = true;
                } else {
                    double b = ((graphHeight - lastEndY) * (x - lastEndX) / (y - lastEndY));
                    x = lastEndX + b;
                }
                y = graphHeight;
                isOverdrawY = isOverdrawEndPoint = true;
            }
            if (lastEndX < 0) { // start left
                double b = ((0 - x) * (y - lastEndY) / (lastEndX - x));
                lastEndY = y - b;
                lastEndX = 0;
            }

            // we need to save the X before it will be corrected when overdraw y
            float orgStartX = (float) lastEndX + (graphLeft + 1);

            if (lastEndY < 0) { // start bottom
                if (!skipDraw) {
                    double b = ((0 - y) * (x - lastEndX) / (lastEndY - y));
                    lastEndX = x - b;
                }
                lastEndY = 0;
                isOverdrawY = true;
            }
            if (lastEndY > graphHeight) { // start top
                // skip when previous and this point is out of bound
                if (!skipDraw) {
                    double b = ((graphHeight - y) * (x - lastEndX) / (lastEndY - y));
                    lastEndX = x - b;
                }
                lastEndY = graphHeight;
                isOverdrawY = true;
            }

            float startX = (float) lastEndX + (graphLeft + 1);
            float startY = (float) (graphTop - lastEndY) + graphHeight;
            float endX = (float) x + (graphLeft + 1);
            float endY = (float) (graphTop - y) + graphHeight;
            float startXAnimated = startX;
            float endXAnimated = endX;

            //                if (endX < startX) {
            //                    // dont draw from right to left
            //                    skipDraw = true;
            //                }

            // NaN can happen when previous and current value is out of y bounds
            if (!skipDraw && !Float.isNaN(startY) && !Float.isNaN(endY)) {
                // animation
                if (mAnimated) {
                    if ((Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) {
                        long currentTime = System.currentTimeMillis();
                        if (mAnimationStart == 0) {
                            // start animation
                            mAnimationStart = currentTime;
                            mAnimationStartFrameNo = 0;
                        } else {
                            // anti-lag: wait a few frames
                            if (mAnimationStartFrameNo < 15) {
                                // second time
                                mAnimationStart = currentTime;
                                mAnimationStartFrameNo++;
                            }
                        }
                        float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION;
                        float factor = mAnimationInterpolator.getInterpolation(timeFactor);
                        if (timeFactor <= 1.0) {
                            startXAnimated = (startX - lastAnimationReferenceX) * factor
                                    + lastAnimationReferenceX;
                            startXAnimated = Math.max(startXAnimated, lastAnimationReferenceX);
                            endXAnimated = (endX - lastAnimationReferenceX) * factor + lastAnimationReferenceX;
                            ViewCompat.postInvalidateOnAnimation(graphView);
                        } else {
                            // animation finished
                            mLastAnimatedValue = valueX;
                        }
                    } else {
                        lastAnimationReferenceX = endX;
                    }
                }

                // draw data point
                if (!isOverdrawEndPoint) {
                    if (mStyles.drawDataPoints) {
                        // draw first datapoint
                        Paint.Style prevStyle = paint.getStyle();
                        paint.setStyle(Paint.Style.FILL);
                        canvas.drawCircle(endXAnimated, endY, mStyles.dataPointsRadius, paint);
                        paint.setStyle(prevStyle);
                    }
                    registerDataPoint(endX, endY, value);
                }

                if (mDrawAsPath) {
                    mPath.moveTo(startXAnimated, startY);
                }
                // performance opt.
                if (Float.isNaN(lastRenderedX) || Math.abs(endX - lastRenderedX) > .3f) {
                    if (mDrawAsPath) {
                        mPath.lineTo(endXAnimated, endY);
                    } else {
                        // render vertical lines that were skipped
                        if (sameXSkip) {
                            sameXSkip = false;
                            renderLine(canvas,
                                    new float[] { lastRenderedX, minYOnSameX, lastRenderedX, maxYOnSameX },
                                    paint);
                        }
                        renderLine(canvas, new float[] { startXAnimated, startY, endXAnimated, endY }, paint);
                    }
                    lastRenderedX = endX;
                } else {
                    // rendering on same x position
                    // save min+max y position and render it as line
                    if (sameXSkip) {
                        minYOnSameX = Math.min(minYOnSameX, endY);
                        maxYOnSameX = Math.max(maxYOnSameX, endY);
                    } else {
                        // first
                        sameXSkip = true;
                        minYOnSameX = Math.min(startY, endY);
                        maxYOnSameX = Math.max(startY, endY);
                    }
                }

            }

            if (mStyles.drawBackground) {
                if (isOverdrawY) {
                    // start draw original x
                    if (firstX == -1) {
                        firstX = orgStartX;
                        firstY = startY;
                        mPathBackground.moveTo(orgStartX, startY);
                    }
                    // from original start to new start
                    mPathBackground.lineTo(startXAnimated, startY);
                }
                if (firstX == -1) {
                    firstX = startXAnimated;
                    firstY = startY;
                    mPathBackground.moveTo(startXAnimated, startY);
                }
                mPathBackground.lineTo(startXAnimated, startY);
                mPathBackground.lineTo(endXAnimated, endY);
            }

            lastUsedEndX = endXAnimated;
            lastUsedEndY = endY;
        } else if (mStyles.drawDataPoints) {
            //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above)
            float first_X = (float) x + (graphLeft + 1);
            float first_Y = (float) (graphTop - y) + graphHeight;

            if (first_X >= graphLeft && first_Y <= (graphTop + graphHeight)) {
                if (mAnimated && (Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) {
                    long currentTime = System.currentTimeMillis();
                    if (mAnimationStart == 0) {
                        // start animation
                        mAnimationStart = currentTime;
                    }
                    float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION;
                    float factor = mAnimationInterpolator.getInterpolation(timeFactor);
                    if (timeFactor <= 1.0) {
                        first_X = (first_X - lastAnimationReferenceX) * factor + lastAnimationReferenceX;
                        ViewCompat.postInvalidateOnAnimation(graphView);
                    } else {
                        // animation finished
                        mLastAnimatedValue = valueX;
                    }
                }

                Paint.Style prevStyle = paint.getStyle();
                paint.setStyle(Paint.Style.FILL);
                canvas.drawCircle(first_X, first_Y, mStyles.dataPointsRadius, paint);
                paint.setStyle(prevStyle);
            }
        }
        lastEndY = orgY;
        lastEndX = orgX;
        i++;
    }

    if (mDrawAsPath) {
        // draw at the end
        canvas.drawPath(mPath, paint);
    }

    if (mStyles.drawBackground && firstX != -1) {
        // end / close path
        if (lastUsedEndY != graphHeight + graphTop) {
            // dont draw line to same point, otherwise the path is completely broken
            mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop);
        }
        mPathBackground.lineTo(firstX, graphHeight + graphTop);
        if (firstY != graphHeight + graphTop) {
            // dont draw line to same point, otherwise the path is completely broken
            mPathBackground.lineTo(firstX, firstY);
        }
        //mPathBackground.close();
        canvas.drawPath(mPathBackground, mPaintBackground);
    }
}

From source file:org.telegram.ui.ThemePreviewActivity.java

@Override
public View createView(Context context) {
    page1 = new FrameLayout(context);
    ActionBarMenu menu = actionBar.createMenu();
    final ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true)
            .setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() {
                @Override// www  .  j  ava 2 s.  c o m
                public void onSearchExpand() {

                }

                @Override
                public boolean canCollapseSearch() {
                    return true;
                }

                @Override
                public void onSearchCollapse() {

                }

                @Override
                public void onTextChanged(EditText editText) {

                }
            });
    item.getSearchField().setHint(LocaleController.getString("Search", R.string.Search));

    actionBar.setBackButtonDrawable(new MenuDrawable());
    actionBar.setAddToContainer(false);
    actionBar.setTitle(LocaleController.getString("ThemePreview", R.string.ThemePreview));

    page1 = new FrameLayout(context) {
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);

            setMeasuredDimension(widthSize, heightSize);

            measureChildWithMargins(actionBar, widthMeasureSpec, 0, heightMeasureSpec, 0);
            int actionBarHeight = actionBar.getMeasuredHeight();
            if (actionBar.getVisibility() == VISIBLE) {
                heightSize -= actionBarHeight;
            }
            FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams();
            layoutParams.topMargin = actionBarHeight;
            listView.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY));

            measureChildWithMargins(floatingButton, widthMeasureSpec, 0, heightMeasureSpec, 0);
        }

        @Override
        protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
            boolean result = super.drawChild(canvas, child, drawingTime);
            if (child == actionBar && parentLayout != null) {
                parentLayout.drawHeaderShadow(canvas,
                        actionBar.getVisibility() == VISIBLE ? actionBar.getMeasuredHeight() : 0);
            }
            return result;
        }
    };
    page1.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    listView = new RecyclerListView(context);
    listView.setVerticalScrollBarEnabled(true);
    listView.setItemAnimator(null);
    listView.setLayoutAnimation(null);
    listView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
    listView.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT
            : RecyclerListView.SCROLLBAR_POSITION_RIGHT);
    page1.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT,
            Gravity.LEFT | Gravity.TOP));

    floatingButton = new ImageView(context);
    floatingButton.setScaleType(ImageView.ScaleType.CENTER);

    Drawable drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(56),
            Theme.getColor(Theme.key_chats_actionBackground),
            Theme.getColor(Theme.key_chats_actionPressedBackground));
    if (Build.VERSION.SDK_INT < 21) {
        Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow).mutate();
        shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY));
        CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0);
        combinedDrawable.setIconSize(AndroidUtilities.dp(56), AndroidUtilities.dp(56));
        drawable = combinedDrawable;
    }
    floatingButton.setBackgroundDrawable(drawable);
    floatingButton.setColorFilter(
            new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_actionIcon), PorterDuff.Mode.MULTIPLY));
    floatingButton.setImageResource(R.drawable.floating_pencil);
    if (Build.VERSION.SDK_INT >= 21) {
        StateListAnimator animator = new StateListAnimator();
        animator.addState(new int[] { android.R.attr.state_pressed },
                ObjectAnimator
                        .ofFloat(floatingButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4))
                        .setDuration(200));
        animator.addState(new int[] {},
                ObjectAnimator
                        .ofFloat(floatingButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2))
                        .setDuration(200));
        floatingButton.setStateListAnimator(animator);
        floatingButton.setOutlineProvider(new ViewOutlineProvider() {
            @SuppressLint("NewApi")
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56));
            }
        });
    }
    page1.addView(floatingButton,
            LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 56 : 60,
                    Build.VERSION.SDK_INT >= 21 ? 56 : 60,
                    (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.BOTTOM,
                    LocaleController.isRTL ? 14 : 0, 0, LocaleController.isRTL ? 0 : 14, 14));

    dialogsAdapter = new DialogsAdapter(context);
    listView.setAdapter(dialogsAdapter);

    page2 = new SizeNotifierFrameLayout(context) {
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);

            setMeasuredDimension(widthSize, heightSize);

            measureChildWithMargins(actionBar2, widthMeasureSpec, 0, heightMeasureSpec, 0);
            int actionBarHeight = actionBar2.getMeasuredHeight();
            if (actionBar2.getVisibility() == VISIBLE) {
                heightSize -= actionBarHeight;
            }
            FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView2.getLayoutParams();
            layoutParams.topMargin = actionBarHeight;
            listView2.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY));
        }

        @Override
        protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
            boolean result = super.drawChild(canvas, child, drawingTime);
            if (child == actionBar2 && parentLayout != null) {
                parentLayout.drawHeaderShadow(canvas,
                        actionBar2.getVisibility() == VISIBLE ? actionBar2.getMeasuredHeight() : 0);
            }
            return result;
        }
    };
    page2.setBackgroundImage(Theme.getCachedWallpaper());

    actionBar2 = createActionBar(context);
    actionBar2.setBackButtonDrawable(new BackDrawable(false));
    actionBar2.setTitle("Reinhardt");
    actionBar2.setSubtitle(LocaleController.formatDateOnline(System.currentTimeMillis() / 1000 - 60 * 60));
    page2.addView(actionBar2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

    listView2 = new RecyclerListView(context);
    listView2.setVerticalScrollBarEnabled(true);
    listView2.setItemAnimator(null);
    listView2.setLayoutAnimation(null);
    listView2.setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4));
    listView2.setClipToPadding(false);
    listView2.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true));
    listView2.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT
            : RecyclerListView.SCROLLBAR_POSITION_RIGHT);
    page2.addView(listView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT,
            Gravity.LEFT | Gravity.TOP));

    messagesAdapter = new MessagesAdapter(context);
    listView2.setAdapter(messagesAdapter);

    fragmentView = new FrameLayout(context);
    FrameLayout frameLayout = (FrameLayout) fragmentView;

    final ViewPager viewPager = new ViewPager(context);
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            dotsContainer.invalidate();
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
    viewPager.setAdapter(new PagerAdapter() {

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return object == view;
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_UNCHANGED;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = position == 0 ? page1 : page2;
            container.addView(view);
            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public void unregisterDataSetObserver(DataSetObserver observer) {
            if (observer != null) {
                super.unregisterDataSetObserver(observer);
            }
        }
    });
    AndroidUtilities.setViewPagerEdgeEffectColor(viewPager, Theme.getColor(Theme.key_actionBarDefault));
    frameLayout.addView(viewPager, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT,
            LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 48));

    View shadow = new View(context);
    shadow.setBackgroundResource(R.drawable.header_shadow_reverse);
    frameLayout.addView(shadow,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 3, Gravity.LEFT | Gravity.BOTTOM, 0, 0, 0, 48));

    FrameLayout bottomLayout = new FrameLayout(context);
    bottomLayout.setBackgroundColor(0xffffffff);
    frameLayout.addView(bottomLayout,
            LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM));

    dotsContainer = new View(context) {

        private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        @Override
        protected void onDraw(Canvas canvas) {
            int selected = viewPager.getCurrentItem();
            for (int a = 0; a < 2; a++) {
                paint.setColor(a == selected ? 0xff999999 : 0xffcccccc);
                canvas.drawCircle(AndroidUtilities.dp(3 + 15 * a), AndroidUtilities.dp(4),
                        AndroidUtilities.dp(3), paint);
            }
        }
    };
    bottomLayout.addView(dotsContainer, LayoutHelper.createFrame(22, 8, Gravity.CENTER));

    TextView cancelButton = new TextView(context);
    cancelButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    cancelButton.setTextColor(0xff19a7e8);
    cancelButton.setGravity(Gravity.CENTER);
    cancelButton.setBackgroundDrawable(Theme.createSelectorDrawable(0x2f000000, 0));
    cancelButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
    cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
    cancelButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    bottomLayout.addView(cancelButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
    cancelButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Theme.applyPreviousTheme();
            parentLayout.rebuildAllFragmentViews(false);
            finishFragment();
        }
    });

    TextView doneButton = new TextView(context);
    doneButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    doneButton.setTextColor(0xff19a7e8);
    doneButton.setGravity(Gravity.CENTER);
    doneButton.setBackgroundDrawable(Theme.createSelectorDrawable(0x2f000000, 0));
    doneButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
    doneButton.setText(LocaleController.getString("ApplyTheme", R.string.ApplyTheme).toUpperCase());
    doneButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    bottomLayout.addView(doneButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,
            LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.RIGHT));
    doneButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            applied = true;
            parentLayout.rebuildAllFragmentViews(false);
            Theme.applyThemeFile(themeFile, applyingTheme.name, false);
            finishFragment();
        }
    });

    return fragmentView;
}

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.
 *///ww w .  j a v a2  s.co  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:org.telegram.ui.SettingsActivity.java

@Override
public View createView(Context context) {
    actionBar.setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue));
    actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_avatar_actionBarSelectorBlue), false);
    actionBar.setItemsColor(Theme.getColor(Theme.key_avatar_actionBarIconBlue), false);
    actionBar.setBackButtonImage(R.drawable.ic_ab_back);
    actionBar.setAddToContainer(false);//from  www .j av a2 s . c o  m
    extraHeight = 88;
    if (AndroidUtilities.isTablet()) {
        actionBar.setOccupyStatusBar(false);
    }
    actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
        @Override
        public void onItemClick(int id) {
            if (id == -1) {
                finishFragment();
            } else if (id == edit_name) {
                presentFragment(new ChangeNameActivity());
            } else if (id == logout) {
                presentFragment(new LogoutActivity());
            }
        }
    });
    ActionBarMenu menu = actionBar.createMenu();
    ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other);
    item.addSubItem(edit_name, LocaleController.getString("EditName", R.string.EditName));
    item.addSubItem(logout, LocaleController.getString("LogOut", R.string.LogOut));

    int scrollTo;
    int scrollToPosition = 0;
    Object writeButtonTag = null;
    if (listView != null) {
        scrollTo = layoutManager.findFirstVisibleItemPosition();
        View topView = layoutManager.findViewByPosition(scrollTo);
        if (topView != null) {
            scrollToPosition = topView.getTop();
        } else {
            scrollTo = -1;
        }
        writeButtonTag = writeButton.getTag();
    } else {
        scrollTo = -1;
    }

    listAdapter = new ListAdapter(context);

    fragmentView = new FrameLayout(context) {
        @Override
        protected boolean drawChild(@NonNull Canvas canvas, @NonNull View child, long drawingTime) {
            if (child == listView) {
                boolean result = super.drawChild(canvas, child, drawingTime);
                if (parentLayout != null) {
                    int actionBarHeight = 0;
                    int childCount = getChildCount();
                    for (int a = 0; a < childCount; a++) {
                        View view = getChildAt(a);
                        if (view == child) {
                            continue;
                        }
                        if (view instanceof ActionBar && view.getVisibility() == VISIBLE) {
                            if (((ActionBar) view).getCastShadows()) {
                                actionBarHeight = view.getMeasuredHeight();
                            }
                            break;
                        }
                    }
                    parentLayout.drawHeaderShadow(canvas, actionBarHeight);
                }
                return result;
            } else {
                return super.drawChild(canvas, child, drawingTime);
            }
        }
    };
    fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
    FrameLayout frameLayout = (FrameLayout) fragmentView;

    listView = new RecyclerListView(context);
    listView.setVerticalScrollBarEnabled(false);
    listView.setLayoutManager(
            layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) {
                @Override
                public boolean supportsPredictiveItemAnimations() {
                    return false;
                }
            });
    listView.setGlowColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue));
    frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT,
            Gravity.TOP | Gravity.LEFT));
    listView.setAdapter(listAdapter);
    listView.setItemAnimator(null);
    listView.setLayoutAnimation(null);
    listView.setOnItemClickListener((view, position) -> {
        if (position == notificationRow) {
            presentFragment(new NotificationsSettingsActivity());
        } else if (position == privacyRow) {
            presentFragment(new PrivacySettingsActivity());
        } else if (position == dataRow) {
            presentFragment(new DataSettingsActivity());
        } else if (position == chatRow) {
            presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC));
        } else if (position == helpRow) {
            BottomSheet.Builder builder = new BottomSheet.Builder(context);
            builder.setApplyTopPadding(false);

            LinearLayout linearLayout = new LinearLayout(context);
            linearLayout.setOrientation(LinearLayout.VERTICAL);

            HeaderCell headerCell = new HeaderCell(context, true, 23, 15, false);
            headerCell.setHeight(47);
            headerCell.setText(LocaleController.getString("SettingsHelp", R.string.SettingsHelp));
            linearLayout.addView(headerCell);

            LinearLayout linearLayoutInviteContainer = new LinearLayout(context);
            linearLayoutInviteContainer.setOrientation(LinearLayout.VERTICAL);
            linearLayout.addView(linearLayoutInviteContainer,
                    LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));

            int count = 6;
            for (int a = 0; a < count; a++) {
                if (a >= 3 && a <= 4 && !BuildVars.LOGS_ENABLED || a == 5 && !BuildVars.DEBUG_VERSION) {
                    continue;
                }
                TextCell textCell = new TextCell(context);
                String text;
                switch (a) {
                case 0:
                    text = LocaleController.getString("AskAQuestion", R.string.AskAQuestion);
                    break;
                case 1:
                    text = LocaleController.getString("TelegramFAQ", R.string.TelegramFAQ);
                    break;
                case 2:
                    text = LocaleController.getString("PrivacyPolicy", R.string.PrivacyPolicy);
                    break;
                case 3:
                    text = LocaleController.getString("DebugSendLogs", R.string.DebugSendLogs);
                    break;
                case 4:
                    text = LocaleController.getString("DebugClearLogs", R.string.DebugClearLogs);
                    break;
                case 5:
                default:
                    text = "Switch Backend";
                    break;
                }
                textCell.setText(text,
                        BuildVars.LOGS_ENABLED || BuildVars.DEBUG_VERSION ? a != count - 1 : a != 2);
                textCell.setTag(a);
                textCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
                linearLayoutInviteContainer.addView(textCell,
                        LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
                textCell.setOnClickListener(v2 -> {
                    Integer tag = (Integer) v2.getTag();
                    switch (tag) {
                    case 0: {
                        showDialog(AlertsCreator.createSupportAlert(SettingsActivity.this));
                        break;
                    }
                    case 1:
                        Browser.openUrl(getParentActivity(),
                                LocaleController.getString("TelegramFaqUrl", R.string.TelegramFaqUrl));
                        break;
                    case 2:
                        Browser.openUrl(getParentActivity(),
                                LocaleController.getString("PrivacyPolicyUrl", R.string.PrivacyPolicyUrl));
                        break;
                    case 3:
                        sendLogs();
                        break;
                    case 4:
                        FileLog.cleanupLogs();
                        break;
                    case 5: {
                        if (getParentActivity() == null) {
                            return;
                        }
                        AlertDialog.Builder builder1 = new AlertDialog.Builder(getParentActivity());
                        builder1.setMessage(LocaleController.getString("AreYouSure", R.string.AreYouSure));
                        builder1.setTitle(LocaleController.getString("AppName", R.string.AppName));
                        builder1.setPositiveButton(LocaleController.getString("OK", R.string.OK),
                                (dialogInterface, i) -> {
                                    SharedConfig.pushAuthKey = null;
                                    SharedConfig.pushAuthKeyId = null;
                                    SharedConfig.saveConfig();
                                    ConnectionsManager.getInstance(currentAccount).switchBackend();
                                });
                        builder1.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                        showDialog(builder1.create());
                        break;
                    }
                    }
                    builder.getDismissRunnable().run();
                });
            }
            builder.setCustomView(linearLayout);
            showDialog(builder.create());
        } else if (position == languageRow) {
            presentFragment(new LanguageSelectActivity());
        } else if (position == usernameRow) {
            presentFragment(new ChangeUsernameActivity());
        } else if (position == bioRow) {
            if (userInfo != null) {
                presentFragment(new ChangeBioActivity());
            }
        } else if (position == numberRow) {
            presentFragment(new ChangePhoneHelpActivity());
        }
    });

    listView.setOnItemLongClickListener(new RecyclerListView.OnItemLongClickListener() {

        private int pressCount = 0;

        @Override
        public boolean onItemClick(View view, int position) {
            if (position == versionRow) {
                pressCount++;
                if (pressCount >= 2 || BuildVars.DEBUG_PRIVATE_VERSION) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                    builder.setTitle(LocaleController.getString("DebugMenu", R.string.DebugMenu));
                    CharSequence[] items;
                    items = new CharSequence[] {
                            LocaleController.getString("DebugMenuImportContacts",
                                    R.string.DebugMenuImportContacts),
                            LocaleController.getString("DebugMenuReloadContacts",
                                    R.string.DebugMenuReloadContacts),
                            LocaleController.getString("DebugMenuResetContacts",
                                    R.string.DebugMenuResetContacts),
                            LocaleController.getString("DebugMenuResetDialogs", R.string.DebugMenuResetDialogs),
                            BuildVars.LOGS_ENABLED
                                    ? LocaleController.getString("DebugMenuDisableLogs",
                                            R.string.DebugMenuDisableLogs)
                                    : LocaleController.getString("DebugMenuEnableLogs",
                                            R.string.DebugMenuEnableLogs),
                            SharedConfig.inappCamera
                                    ? LocaleController.getString("DebugMenuDisableCamera",
                                            R.string.DebugMenuDisableCamera)
                                    : LocaleController.getString("DebugMenuEnableCamera",
                                            R.string.DebugMenuEnableCamera),
                            LocaleController.getString("DebugMenuClearMediaCache",
                                    R.string.DebugMenuClearMediaCache),
                            LocaleController.getString("DebugMenuCallSettings", R.string.DebugMenuCallSettings),
                            null, BuildVars.DEBUG_PRIVATE_VERSION ? "Check for app updates" : null };
                    builder.setItems(items, (dialog, which) -> {
                        if (which == 0) {
                            UserConfig.getInstance(currentAccount).syncContacts = true;
                            UserConfig.getInstance(currentAccount).saveConfig(false);
                            ContactsController.getInstance(currentAccount).forceImportContacts();
                        } else if (which == 1) {
                            ContactsController.getInstance(currentAccount).loadContacts(false, 0);
                        } else if (which == 2) {
                            ContactsController.getInstance(currentAccount).resetImportedContacts();
                        } else if (which == 3) {
                            MessagesController.getInstance(currentAccount).forceResetDialogs();
                        } else if (which == 4) {
                            BuildVars.LOGS_ENABLED = !BuildVars.LOGS_ENABLED;
                            SharedPreferences sharedPreferences = ApplicationLoader.applicationContext
                                    .getSharedPreferences("systemConfig", Context.MODE_PRIVATE);
                            sharedPreferences.edit().putBoolean("logsEnabled", BuildVars.LOGS_ENABLED).commit();
                        } else if (which == 5) {
                            SharedConfig.toggleInappCamera();
                        } else if (which == 6) {
                            MessagesStorage.getInstance(currentAccount).clearSentMedia();
                            SharedPreferences.Editor editor = MessagesController.getGlobalMainSettings().edit();
                            SharedConfig.setNoSoundHintShowed(false);
                        } else if (which == 7) {
                            VoIPHelper.showCallDebugSettings(getParentActivity());
                        } else if (which == 8) {
                            SharedConfig.toggleRoundCamera16to9();
                        } else if (which == 9) {
                            ((LaunchActivity) getParentActivity()).checkAppUpdate(true);
                        }
                    });
                    builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
                    showDialog(builder.create());
                } else {
                    try {
                        Toast.makeText(getParentActivity(), "\\_()_/", Toast.LENGTH_SHORT).show();
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                }
                return true;
            }
            return false;
        }
    });

    frameLayout.addView(actionBar);

    extraHeightView = new View(context);
    extraHeightView.setPivotY(0);
    extraHeightView.setBackgroundColor(Theme.getColor(Theme.key_avatar_backgroundActionBarBlue));
    frameLayout.addView(extraHeightView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 88));

    shadowView = new View(context);
    shadowView.setBackgroundResource(R.drawable.header_shadow);
    frameLayout.addView(shadowView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 3));

    avatarContainer = new FrameLayout(context);
    avatarContainer.setPivotX(LocaleController.isRTL ? AndroidUtilities.dp(42) : 0);
    avatarContainer.setPivotY(0);
    frameLayout.addView(avatarContainer,
            LayoutHelper.createFrame(42, 42,
                    Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT),
                    (LocaleController.isRTL ? 0 : 64), 0, (LocaleController.isRTL ? 64 : 0), 0));
    avatarContainer.setOnClickListener(v -> {
        if (avatar != null) {
            return;
        }
        TLRPC.User user = MessagesController.getInstance(currentAccount)
                .getUser(UserConfig.getInstance(currentAccount).getClientUserId());
        if (user != null && user.photo != null && user.photo.photo_big != null) {
            PhotoViewer.getInstance().setParentActivity(getParentActivity());
            PhotoViewer.getInstance().openPhoto(user.photo.photo_big, provider);
        }
    });

    avatarImage = new BackupImageView(context);
    avatarImage.setRoundRadius(AndroidUtilities.dp(21));
    avatarContainer.addView(avatarImage, LayoutHelper.createFrame(42, 42));

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(0x55000000);

    avatarProgressView = new RadialProgressView(context) {
        @Override
        protected void onDraw(Canvas canvas) {
            if (avatarImage != null && avatarImage.getImageReceiver().hasNotThumb()) {
                paint.setAlpha((int) (0x55 * avatarImage.getImageReceiver().getCurrentAlpha()));
                canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, AndroidUtilities.dp(21),
                        paint);
            }
            super.onDraw(canvas);
        }
    };
    avatarProgressView.setSize(AndroidUtilities.dp(26));
    avatarProgressView.setProgressColor(0xffffffff);
    avatarContainer.addView(avatarProgressView, LayoutHelper.createFrame(42, 42));

    showAvatarProgress(false, false);

    nameTextView = new TextView(context) {
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setPivotX(LocaleController.isRTL ? getMeasuredWidth() : 0);
        }
    };
    nameTextView.setTextColor(Theme.getColor(Theme.key_profile_title));
    nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
    nameTextView.setLines(1);
    nameTextView.setMaxLines(1);
    nameTextView.setSingleLine(true);
    nameTextView.setEllipsize(TextUtils.TruncateAt.END);
    nameTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
    nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
    nameTextView.setPivotY(0);
    frameLayout.addView(nameTextView,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT,
                    (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP,
                    LocaleController.isRTL ? 48 : 118, 0, LocaleController.isRTL ? 118 : 48, 0));

    onlineTextView = new TextView(context);
    onlineTextView.setTextColor(Theme.getColor(Theme.key_avatar_subtitleInProfileBlue));
    onlineTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
    onlineTextView.setLines(1);
    onlineTextView.setMaxLines(1);
    onlineTextView.setSingleLine(true);
    onlineTextView.setEllipsize(TextUtils.TruncateAt.END);
    onlineTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
    frameLayout.addView(onlineTextView,
            LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT,
                    (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP,
                    LocaleController.isRTL ? 48 : 118, 0, LocaleController.isRTL ? 118 : 48, 0));

    writeButton = new ImageView(context);
    Drawable drawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(56),
            Theme.getColor(Theme.key_profile_actionBackground),
            Theme.getColor(Theme.key_profile_actionPressedBackground));
    if (Build.VERSION.SDK_INT < 21) {
        Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow_profile)
                .mutate();
        shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY));
        CombinedDrawable combinedDrawable = new CombinedDrawable(shadowDrawable, drawable, 0, 0);
        combinedDrawable.setIconSize(AndroidUtilities.dp(56), AndroidUtilities.dp(56));
        drawable = combinedDrawable;
    }
    writeButton.setBackgroundDrawable(drawable);
    writeButton.setImageResource(R.drawable.menu_camera_av);
    writeButton.setColorFilter(
            new PorterDuffColorFilter(Theme.getColor(Theme.key_profile_actionIcon), PorterDuff.Mode.MULTIPLY));
    writeButton.setScaleType(ImageView.ScaleType.CENTER);
    if (Build.VERSION.SDK_INT >= 21) {
        StateListAnimator animator = new StateListAnimator();
        animator.addState(new int[] { android.R.attr.state_pressed },
                ObjectAnimator
                        .ofFloat(writeButton, "translationZ", AndroidUtilities.dp(2), AndroidUtilities.dp(4))
                        .setDuration(200));
        animator.addState(new int[] {},
                ObjectAnimator
                        .ofFloat(writeButton, "translationZ", AndroidUtilities.dp(4), AndroidUtilities.dp(2))
                        .setDuration(200));
        writeButton.setStateListAnimator(animator);
        writeButton.setOutlineProvider(new ViewOutlineProvider() {
            @SuppressLint("NewApi")
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setOval(0, 0, AndroidUtilities.dp(56), AndroidUtilities.dp(56));
            }
        });
    }
    frameLayout.addView(writeButton,
            LayoutHelper.createFrame(Build.VERSION.SDK_INT >= 21 ? 56 : 60,
                    Build.VERSION.SDK_INT >= 21 ? 56 : 60,
                    (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP,
                    LocaleController.isRTL ? 16 : 0, 0, LocaleController.isRTL ? 0 : 16, 0));
    writeButton.setOnClickListener(v -> {
        TLRPC.User user = MessagesController.getInstance(currentAccount)
                .getUser(UserConfig.getInstance(currentAccount).getClientUserId());
        if (user == null) {
            user = UserConfig.getInstance(currentAccount).getCurrentUser();
        }
        if (user == null) {
            return;
        }
        imageUpdater.openMenu(
                user.photo != null && user.photo.photo_big != null
                        && !(user.photo instanceof TLRPC.TL_userProfilePhotoEmpty),
                () -> MessagesController.getInstance(currentAccount).deleteUserPhoto(null));
    });

    if (scrollTo != -1) {
        layoutManager.scrollToPositionWithOffset(scrollTo, scrollToPosition);

        if (writeButtonTag != null) {
            writeButton.setTag(0);
            writeButton.setScaleX(0.2f);
            writeButton.setScaleY(0.2f);
            writeButton.setAlpha(0.0f);
            writeButton.setVisibility(View.GONE);
        }
    }

    needLayout();

    listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (layoutManager.getItemCount() == 0) {
                return;
            }
            int height = 0;
            View child = recyclerView.getChildAt(0);
            if (child != null) {
                if (layoutManager.findFirstVisibleItemPosition() == 0) {
                    height = AndroidUtilities.dp(88) + (child.getTop() < 0 ? child.getTop() : 0);
                }
                if (extraHeight != height) {
                    extraHeight = height;
                    needLayout();
                }
            }
        }
    });

    return fragmentView;
}