List of usage examples for android.graphics Canvas save
public int save()
From source file:com.guodong.sun.guodong.widget.ZoomImageView.java
@Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) { return; // couldn't resolve the URI }/*from w ww . j a va 2 s . c o m*/ if (mState == STATE_TRANSFORM_IN || mState == STATE_TRANSFORM_OUT) { if (mTransformStart) { initTransform(); } if (mTransfrom == null) { super.onDraw(canvas); return; } if (mTransformStart) { if (mState == STATE_TRANSFORM_IN) { mTransfrom.initStartIn(); } else { mTransfrom.initStartOut(); } } if (mTransformStart) { Log.d("Dean", "mTransfrom.startScale:" + mTransfrom.startScale); Log.d("Dean", "mTransfrom.startScale:" + mTransfrom.endScale); Log.d("Dean", "mTransfrom.scale:" + mTransfrom.scale); Log.d("Dean", "mTransfrom.startRect:" + mTransfrom.startRect.toString()); Log.d("Dean", "mTransfrom.endRect:" + mTransfrom.endRect.toString()); Log.d("Dean", "mTransfrom.rect:" + mTransfrom.rect.toString()); } mPaint.setAlpha(mBgAlpha); canvas.drawPaint(mPaint); int saveCount = canvas.getSaveCount(); canvas.save(); // ?Matrix getBmpMatrix(); canvas.translate(mTransfrom.rect.left, mTransfrom.rect.top); canvas.clipRect(0, 0, mTransfrom.rect.width, mTransfrom.rect.height); canvas.concat(mSmoothMatrix); getDrawable().draw(canvas); canvas.restoreToCount(saveCount); if (mTransformStart) { mTransformStart = false; startTransform(mState); } } else { //Transform In???Activity?? mPaint.setAlpha(255); canvas.drawPaint(mPaint); super.onDraw(canvas); } }
From source file:com.pdftron.pdf.tools.Tool.java
public void onDraw(Canvas canvas, android.graphics.Matrix tfm) { // Draw page number if (mShowPageNum && mPageNumberIndicatorVisible) { int width = mPDFView.getWidth(); int height = mPDFView.getHeight(); int page_num = mPDFView.getCurrentPage(); boolean restore = false; float yOffset = 0; try {/*www.java 2s . c o m*/ // During page sliding, PDFViewCtrl might apply extra transformation // matrix to Canvas for animation. However, page number should not // move; hence applying the inverse to offset it. if (!tfm.isIdentity()) { canvas.save(); restore = true; tfm.invert(mTempMtx1); canvas.getMatrix(mTempMtx2); mTempMtx2.postConcat(mTempMtx1); canvas.setMatrix(mTempMtx2); // Workaround for bug found in Android > ICS with hardware acceleration turned // ON. See http://code.google.com/p/android/issues/detail?id=24517 for more info if (Build.VERSION.SDK_INT >= 14 /*Build.VERSION_CODES.ICE_CREAM_SANDWICH*/ && mPDFView.isHardwareAccelerated()) { Rect rectangle = new Rect(); ((android.app.Activity) mPDFView.getContext()).getWindow().getDecorView() .getWindowVisibleDisplayFrame(rectangle); yOffset = rectangle.top; } } int page_count = mPDFView.getDoc().getPageCount(); String str = String.format(getStringFromResId(R.string.tools_misc_pagerange), page_num, page_count); Rect r = new Rect(); mPaint4PageNum.getTextBounds(str, 0, str.length(), r); float str_width = r.width(); float str_height = r.height(); float margin = str_height / 1.5f; float left = width - str_width * 1.5f - margin + mPDFView.getScrollX(); float top = mPDFView.getScrollY() + height - mPageNumPosAdjust - str_height * 3.0f + yOffset; float right = left + str_width + margin * 2; float bottom = top + str_height + margin * 2; mTempPageDrawingRectF.set(left, top, right, bottom); mPaint4PageNum.setColor( mPDFView.getContext().getResources().getColor(R.color.tools_pageindicator_background)); canvas.drawRoundRect(mTempPageDrawingRectF, margin, margin, mPaint4PageNum); mPaint4PageNum .setColor(mPDFView.getContext().getResources().getColor(R.color.tools_pageindicator_text)); left += margin; top += str_height / 2 + margin + mPaint4PageNum.descent(); canvas.drawText(str, left, top - 0.5f, mPaint4PageNum); } catch (Exception e) { } finally { if (restore) { canvas.restore(); } } } }
From source file:org.chromium.chrome.browser.toolbar.ToolbarPhone.java
private boolean drawLocationBar(Canvas canvas, long drawingTime) { boolean clipped = false; if (mLocationBarBackground != null && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode)) { canvas.save(); int backgroundAlpha; if (mTabSwitcherModeAnimation != null) { // Fade out/in the location bar towards the beginning of the animations to avoid // large jumps of stark white. backgroundAlpha = (int) (Math.pow(mLocationBar.getAlpha(), 3) * mLocationBarBackgroundAlpha); } else if (getToolbarDataProvider().isUsingBrandColor() && !mBrandColorTransitionActive) { backgroundAlpha = mUnfocusedLocationBarUsesTransparentBg ? (int) (MathUtils.interpolate(LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA, 255, mUrlExpansionPercent)) : 255;/*w w w .ja v a 2 s.com*/ } else { backgroundAlpha = mLocationBarBackgroundAlpha; } mLocationBarBackground.setAlpha(backgroundAlpha); if ((mLocationBar.getAlpha() > 0 || mForceDrawLocationBarBackground) && !mTextureCaptureMode) { mLocationBarBackground.setBounds( mLocationBarBackgroundBounds.left + mLocationBarBackgroundNtpOffset.left - mLocationBarBackgroundPadding.left, mLocationBarBackgroundBounds.top + mLocationBarBackgroundNtpOffset.top - mLocationBarBackgroundPadding.top, mLocationBarBackgroundBounds.right + mLocationBarBackgroundNtpOffset.right + mLocationBarBackgroundPadding.right, mLocationBarBackgroundBounds.bottom + mLocationBarBackgroundNtpOffset.bottom + mLocationBarBackgroundPadding.bottom); mLocationBarBackground.draw(canvas); } float locationBarClipLeft = mLocationBarBackgroundBounds.left + mLocationBarBackgroundNtpOffset.left; float locationBarClipRight = mLocationBarBackgroundBounds.right + mLocationBarBackgroundNtpOffset.right; float locationBarClipTop = mLocationBarBackgroundBounds.top + mLocationBarBackgroundNtpOffset.top; float locationBarClipBottom = mLocationBarBackgroundBounds.bottom + mLocationBarBackgroundNtpOffset.bottom; // When unexpanded, the location bar's visible content boundaries are inset from the // viewport used to draw the background. During expansion transitions, compensation // is applied to increase the clip regions such that when the location bar converts // to the narrower collapsed layout that the visible content is the same. if (mUrlExpansionPercent != 1f) { int leftDelta = mUnfocusedLocationBarLayoutLeft - getViewBoundsLeftOfLocationBar(mVisualState); int rightDelta = getViewBoundsRightOfLocationBar(mVisualState) - mUnfocusedLocationBarLayoutLeft - mUnfocusedLocationBarLayoutWidth; float inversePercent = 1f - mUrlExpansionPercent; locationBarClipLeft += leftDelta * inversePercent; locationBarClipRight -= rightDelta * inversePercent; } // Clip the location bar child to the URL viewport calculated in onDraw. canvas.clipRect(locationBarClipLeft, locationBarClipTop, locationBarClipRight, locationBarClipBottom); clipped = true; } boolean retVal = super.drawChild(canvas, mLocationBar, drawingTime); if (clipped) canvas.restore(); return retVal; }
From source file:org.akop.ararat.view.CrosswordView.java
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); constrainTranslation();/*w w w .j a v a 2 s . c o m*/ canvas.save(); canvas.clipRect(mContentRect); canvas.translate(mBitmapOffset.x, mBitmapOffset.y); canvas.scale(mBitmapScale, mBitmapScale); if (mPuzzleBitmap != null) { canvas.drawBitmap(mPuzzleBitmap, 0, 0, mBitmapPaint); } else { // Perform a fast, barebones render so that the screen doesn't // look completely empty mInPlaceRenderer.renderPuzzle(canvas, mRenderScale, true); } canvas.restore(); }
From source file:com.mixiaoxiao.support.widget.SmoothSwitch.java
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (!isEnabled()) {//wangbin added this line if (mThumbDrawable != null) { mThumbDrawable.setColor(getDisableColor(isChecked() ? mThumbColorOn : mThumbColorOff)); }/* w w w . ja va 2 s . com*/ if (mTrackDrawable != null) { mTrackDrawable.setColor(getDisableColor(isChecked() ? mTrackColorOn : mTrackColorOff)); } } final Rect padding = mTempRect; final Drawable trackDrawable = mTrackDrawable; if (trackDrawable != null) { trackDrawable.getPadding(padding); } else { padding.setEmpty(); } final int switchTop = mSwitchTop; final int switchBottom = mSwitchBottom; final int switchInnerTop = switchTop + padding.top; final int switchInnerBottom = switchBottom - padding.bottom; final Drawable thumbDrawable = mThumbDrawable; if (trackDrawable != null) { trackDrawable.draw(canvas); } final int saveCount = canvas.save(); if (thumbDrawable != null) { thumbDrawable.draw(canvas); } final Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout; if (switchText != null) { final int drawableState[] = getDrawableState(); if (mTextColors != null) { mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0)); } mTextPaint.drawableState = drawableState; final int cX; if (thumbDrawable != null) { final Rect bounds = thumbDrawable.getBounds(); cX = bounds.left + bounds.right; } else { cX = getWidth(); } final int left = cX / 2 - switchText.getWidth() / 2; final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2; canvas.translate(left, top); switchText.draw(canvas); } canvas.restoreToCount(saveCount); }
From source file:com.aidy.bottomdrawerlayout.AllDrawerLayout.java
@Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { Log.i(TAG, "drawChild()"); final int height = getHeight(); final boolean drawingContent = isContentView(child); int clipLeft = 0, clipRight = getWidth(); int clipTop = 0, clipBottom = getHeight(); final int restoreCount = canvas.save(); if (drawingContent) { final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View v = getChildAt(i); if (v == child || v.getVisibility() != VISIBLE || !hasOpaqueBackground(v) || !isDrawerView(v) || v.getHeight() < height) { Log.i(TAG, "drawChild() -- 0"); continue; }//from ww w. j av a2 s .c o m switch (getDrawerViewAbsoluteGravity(v)) { case Gravity.LEFT: Log.i(TAG, "drawChild() -- 1"); if (checkDrawerViewAbsoluteGravity(v, Gravity.LEFT)) { final int vright = v.getRight(); if (vright > clipLeft) clipLeft = vright; } break; case Gravity.RIGHT: Log.i(TAG, "drawChild() -- 2"); if (checkDrawerViewAbsoluteGravity(v, Gravity.RIGHT)) { final int vleft = v.getLeft(); if (vleft < clipRight) clipRight = vleft; } break; case Gravity.TOP: Log.i(TAG, "drawChild() -- 3"); if (checkDrawerViewAbsoluteGravity(v, Gravity.TOP)) { final int vbottom = v.getBottom(); if (vbottom > clipTop) { clipTop = vbottom; } } break; case Gravity.BOTTOM: Log.i(TAG, "drawChild() -- 4"); if (checkDrawerViewAbsoluteGravity(v, Gravity.BOTTOM)) { final int vtop = v.getTop(); if (vtop < clipBottom) { clipBottom = vtop; } } break; default: Log.i(TAG, "drawChild() -- 5"); final int vtop = v.getTop(); if (vtop < clipBottom) { clipBottom = vtop; } break; } } canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom); } final boolean result = super.drawChild(canvas, child, drawingTime); canvas.restoreToCount(restoreCount); if (mScrimOpacity > 0 && drawingContent) { Log.i(TAG, "drawChild() -- drawingContent"); final int baseAlpha = (mScrimColor & 0xff000000) >>> 24; final int imag = (int) (baseAlpha * mScrimOpacity); final int color = imag << 24 | (mScrimColor & 0xffffff); mScrimPaint.setColor(color); canvas.drawRect(clipLeft, clipTop, clipRight, clipBottom, mScrimPaint); } else if (mShadowLeft != null && checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) { Log.i(TAG, "drawChild() -- LEFT"); final int shadowWidth = mShadowLeft.getIntrinsicWidth(); final int childRight = child.getRight(); final int drawerPeekDistance = mLeftDragger.getEdgeSize(); final float alpha = Math.max(0, Math.min((float) childRight / drawerPeekDistance, 1.f)); mShadowLeft.setBounds(childRight, child.getTop(), childRight + shadowWidth, child.getBottom()); mShadowLeft.setAlpha((int) (0xff * alpha)); mShadowLeft.draw(canvas); } else if (mShadowRight != null && checkDrawerViewAbsoluteGravity(child, Gravity.RIGHT)) { Log.i(TAG, "drawChild() -- Gravity.RIGHT"); final int shadowWidth = mShadowRight.getIntrinsicWidth(); final int childLeft = child.getLeft(); final int showing = getWidth() - childLeft; final int drawerPeekDistance = mRightDragger.getEdgeSize(); final float alpha = Math.max(0, Math.min((float) showing / drawerPeekDistance, 1.f)); mShadowRight.setBounds(childLeft - shadowWidth, child.getTop(), childLeft, child.getBottom()); mShadowRight.setAlpha((int) (0xff * alpha)); mShadowRight.draw(canvas); } else if (mShadowTop != null && checkDrawerViewAbsoluteGravity(child, Gravity.TOP)) { Log.i(TAG, "drawChild() -- Gravity.TOP"); final int shadowHeight = mShadowTop.getIntrinsicHeight(); final int childBottom = child.getBottom(); final int drawerPeekDistance = mTopDragger.getEdgeSize(); final float alpha = Math.max(0, Math.min((float) childBottom / drawerPeekDistance, 1.f)); mShadowTop.setBounds(child.getLeft(), childBottom, child.getRight(), childBottom + shadowHeight); mShadowTop.setAlpha((int) (0xff * alpha)); mShadowTop.draw(canvas); } else if (mShadowBottom != null && checkDrawerViewAbsoluteGravity(child, Gravity.BOTTOM)) { Log.i(TAG, "drawChild() -- Gravity.BOTTOM"); final int shadowHeight = mShadowBottom.getIntrinsicWidth(); final int childTop = child.getTop(); final int showing = getHeight() - childTop; final int drawerPeekDistance = mBottomDragger.getEdgeSize(); final float alpha = Math.max(0, Math.min((float) showing / drawerPeekDistance, 1.f)); mShadowRight.setBounds(child.getLeft(), childTop - shadowHeight, child.getRight(), childTop); mShadowRight.setAlpha((int) (0xff * alpha)); mShadowRight.draw(canvas); } return result; }
From source file:org.chromium.chrome.browser.toolbar.ToolbarPhone.java
/** * When entering and exiting the TabSwitcher mode, we fade out or fade in the browsing * mode of the toolbar on top of the TabSwitcher mode version of it. We do this by * drawing all of the browsing mode views on top of the android view. */// ww w .j a v a2 s . c o m private void drawTabSwitcherAnimationOverlay(Canvas canvas, float animationProgress) { if (!isNativeLibraryReady()) return; float floatAlpha = 1 - animationProgress; int rgbAlpha = (int) (255 * floatAlpha); canvas.save(); canvas.translate(0, -animationProgress * mBackgroundOverlayBounds.height()); canvas.clipRect(mBackgroundOverlayBounds); float previousAlpha = 0.f; if (mHomeButton.getVisibility() != View.GONE) { // Draw the New Tab button used in the URL view. previousAlpha = mHomeButton.getAlpha(); mHomeButton.setAlpha(previousAlpha * floatAlpha); drawChild(canvas, mHomeButton, SystemClock.uptimeMillis()); mHomeButton.setAlpha(previousAlpha); } // Draw the location/URL bar. previousAlpha = mLocationBar.getAlpha(); mLocationBar.setAlpha(previousAlpha * floatAlpha); // If the location bar is now fully transparent, do not bother drawing it. if (mLocationBar.getAlpha() != 0) { drawChild(canvas, mLocationBar, SystemClock.uptimeMillis()); } mLocationBar.setAlpha(previousAlpha); // Draw the tab stack button and associated text. translateCanvasToView(this, mToolbarButtonsContainer, canvas); if (mTabSwitcherAnimationTabStackDrawable != null && mToggleTabStackButton != null && mUrlExpansionPercent != 1f) { // Draw the tab stack button image. canvas.save(); translateCanvasToView(mToolbarButtonsContainer, mToggleTabStackButton, canvas); int backgroundWidth = mToggleTabStackButton.getDrawable().getIntrinsicWidth(); int backgroundHeight = mToggleTabStackButton.getDrawable().getIntrinsicHeight(); int backgroundLeft = (mToggleTabStackButton.getWidth() - mToggleTabStackButton.getPaddingLeft() - mToggleTabStackButton.getPaddingRight() - backgroundWidth) / 2; backgroundLeft += mToggleTabStackButton.getPaddingLeft(); int backgroundTop = (mToggleTabStackButton.getHeight() - mToggleTabStackButton.getPaddingTop() - mToggleTabStackButton.getPaddingBottom() - backgroundHeight) / 2; backgroundTop += mToggleTabStackButton.getPaddingTop(); canvas.translate(backgroundLeft, backgroundTop); mTabSwitcherAnimationTabStackDrawable.setAlpha(rgbAlpha); mTabSwitcherAnimationTabStackDrawable.draw(canvas); canvas.restore(); } // Draw the menu button if necessary. if (!mShowMenuBadge && mTabSwitcherAnimationMenuDrawable != null && mUrlExpansionPercent != 1f) { mTabSwitcherAnimationMenuDrawable.setBounds(mMenuButton.getPaddingLeft(), mMenuButton.getPaddingTop(), mMenuButton.getWidth() - mMenuButton.getPaddingRight(), mMenuButton.getHeight() - mMenuButton.getPaddingBottom()); translateCanvasToView(mToolbarButtonsContainer, mMenuButton, canvas); mTabSwitcherAnimationMenuDrawable.setAlpha(rgbAlpha); int color = mUseLightDrawablesForTextureCapture ? mLightModeDefaultColor : mDarkModeDefaultColor; mTabSwitcherAnimationMenuDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); mTabSwitcherAnimationMenuDrawable.draw(canvas); } // Draw the menu badge if necessary. Drawable badgeDrawable = mUseLightDrawablesForTextureCapture ? mTabSwitcherAnimationMenuBadgeLightDrawable : mTabSwitcherAnimationMenuBadgeDarkDrawable; if (mShowMenuBadge && badgeDrawable != null && mUrlExpansionPercent != 1f) { badgeDrawable.setBounds(mMenuBadge.getPaddingLeft(), mMenuBadge.getPaddingTop(), mMenuBadge.getWidth() - mMenuBadge.getPaddingRight(), mMenuBadge.getHeight() - mMenuBadge.getPaddingBottom()); translateCanvasToView(mToolbarButtonsContainer, mMenuBadge, canvas); badgeDrawable.setAlpha(rgbAlpha); badgeDrawable.draw(canvas); } mLightDrawablesUsedForLastTextureCapture = mUseLightDrawablesForTextureCapture; canvas.restore(); }
From source file:com.iangclifton.auid.horizontaliconview.HorizontalIconView.java
@Override protected void onDraw(Canvas canvas) { if (mDrawables == null || mDrawables.isEmpty()) { return;/*from w w w. j a v a 2 s . c o m*/ } final int width = getWidth(); final int paddingBottom = getPaddingBottom(); final int paddingLeft = getPaddingLeft(); final int paddingTop = getPaddingTop(); // Determine edges of visible content final int leftEdge = getScrollX(); final int rightEdge = leftEdge + width; int left = paddingLeft; int top = paddingTop; mSkippedIconCount = 0; final int iconCount = mDrawables.size(); for (int i = 0; i < iconCount; i++) { if (left + mIconSize < leftEdge) { // Icon is too far left to be seen left = left + mIconSize + mIconSpacing; mSkippedIconCount++; continue; } if (left > rightEdge) { // All remaining icons are right of the view break; } // Get a reference to the icon to be drawn final Drawable icon = mDrawables.get(i); icon.setBounds(left, top, left + mIconSize, top + mIconSize); icon.draw(canvas); // Icon was drawn, so track position final int drawnPosition = i - mSkippedIconCount; if (drawnPosition + 1 > mIconPositions.size()) { final Rect rect = icon.copyBounds(); mIconPositions.add(rect); } else { final Rect rect = mIconPositions.get(drawnPosition); icon.copyBounds(rect); } // Update left position left = left + mIconSize + mIconSpacing; } if (mEdgeEffectLeft != null) { if (!mEdgeEffectLeft.isFinished()) { final int restoreCount = canvas.save(); final int height = getHeight() - paddingTop - paddingBottom; canvas.rotate(270); canvas.translate(-height + paddingTop, Math.min(0, leftEdge)); mEdgeEffectLeft.setSize(height, getWidth()); if (mEdgeEffectLeft.draw(canvas)) { postInvalidateOnAnimation(); } canvas.restoreToCount(restoreCount); } if (!mEdgeEffectRight.isFinished()) { final int restoreCount = canvas.save(); final int height = getHeight() - paddingTop - paddingBottom; canvas.rotate(90); canvas.translate(-paddingTop, -(Math.max(mScrollRange, leftEdge) + width)); mEdgeEffectRight.setSize(height, width); if (mEdgeEffectRight.draw(canvas)) { postInvalidateOnAnimation(); } canvas.restoreToCount(restoreCount); } } }
From source file:com.chenglong.muscle.ui.LazyViewPager.java
@Override public void draw(Canvas canvas) { super.draw(canvas); boolean needsInvalidate = false; final int overScrollMode = ViewCompat.getOverScrollMode(this); if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS || (overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && mAdapter != null && mAdapter.getCount() > 1)) { if (!mLeftEdge.isFinished()) { final int restoreCount = canvas.save(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); canvas.rotate(270);/*from w w w. jav a 2 s .c om*/ canvas.translate(-height + getPaddingTop(), 0); mLeftEdge.setSize(height, getWidth()); needsInvalidate |= mLeftEdge.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mRightEdge.isFinished()) { final int restoreCount = canvas.save(); final int width = getWidth(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); final int itemCount = mAdapter != null ? mAdapter.getCount() : 1; canvas.rotate(90); canvas.translate(-getPaddingTop(), -itemCount * (width + mPageMargin) + mPageMargin); mRightEdge.setSize(height, width); needsInvalidate |= mRightEdge.draw(canvas); canvas.restoreToCount(restoreCount); } } else { mLeftEdge.finish(); mRightEdge.finish(); } if (needsInvalidate) { // Keep animating invalidate(); } }
From source file:de.andacaydin.bidirectionalviewpagerlibrary.BiDirectionalViewPager.java
@Override public void draw(Canvas canvas) { super.draw(canvas); boolean needsInvalidate = false; final int overScrollMode = ViewCompat.getOverScrollMode(this); if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS || (overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && mAdapter != null && mAdapter.getCount() > 1)) { if (!mLeftEdge.isFinished()) { final int restoreCount = canvas.save(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); final int width = getWidth(); canvas.rotate(270);/* www .j av a 2 s . c o m*/ canvas.translate(-height + getPaddingTop(), mFirstOffset * width); mLeftEdge.setSize(height, width); needsInvalidate |= mLeftEdge.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mRightEdge.isFinished()) { final int restoreCount = canvas.save(); final int width = getWidth(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); canvas.rotate(90); canvas.translate(-getPaddingTop(), -(mLastOffset + 1) * width); mRightEdge.setSize(height, width); needsInvalidate |= mRightEdge.draw(canvas); canvas.restoreToCount(restoreCount); } } else { mLeftEdge.finish(); mRightEdge.finish(); } if (needsInvalidate) { // Keep animating ViewCompat.postInvalidateOnAnimation(this); } }