use of android.view.animation.Transformation in project WaveSwipeRefreshLayout by recruit-lifestyle.
the class MaterialProgressDrawable method setupAnimators.
private void setupAnimators() {
final Ring ring = mRing;
final Animation animation = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
if (mFinishing) {
applyFinishTranslation(interpolatedTime, ring);
} else {
// The minProgressArc is calculated from 0 to create an
// angle that
// matches the stroke width.
final float minProgressArc = (float) Math.toRadians(ring.getStrokeWidth() / (2 * Math.PI * ring.getCenterRadius()));
final float startingEndTrim = ring.getStartingEndTrim();
final float startingTrim = ring.getStartingStartTrim();
final float startingRotation = ring.getStartingRotation();
// Offset the minProgressArc to where the endTrim is
// located.
final float minArc = MAX_PROGRESS_ARC - minProgressArc;
final float endTrim = startingEndTrim + (minArc * START_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime));
ring.setEndTrim(endTrim);
final float startTrim = startingTrim + (MAX_PROGRESS_ARC * END_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime));
ring.setStartTrim(startTrim);
final float rotation = startingRotation + (0.25f * interpolatedTime);
ring.setRotation(rotation);
float groupRotation = ((720.0f / NUM_POINTS) * interpolatedTime) + (720.0f * (mRotationCount / NUM_POINTS));
setRotation(groupRotation);
}
}
};
animation.setRepeatCount(Animation.INFINITE);
animation.setRepeatMode(Animation.RESTART);
animation.setInterpolator(LINEAR_INTERPOLATOR);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mRotationCount = 0;
}
@Override
public void onAnimationEnd(Animation animation) {
// do nothing
}
@Override
public void onAnimationRepeat(Animation animation) {
ring.storeOriginals();
ring.goToNextColor();
ring.setStartTrim(ring.getEndTrim());
if (mFinishing) {
// finished closing the last ring from the swipe gesture; go
// into progress mode
mFinishing = false;
animation.setDuration(ANIMATION_DURATION);
ring.setShowArrow(false);
} else {
mRotationCount = (mRotationCount + 1) % (NUM_POINTS);
}
}
});
mAnimation = animation;
}
use of android.view.animation.Transformation in project android_frameworks_base by crdroidandroid.
the class WindowStateAnimator method computeShownFrameLocked.
void computeShownFrameLocked(int type) {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation = (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation) ? mAttachedWinAnimator.mTransformation : null;
Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation) ? mAppAnimator.transformation : null;
if (type == TYPE_LEFT || type == TYPE_RIGHT) {
updatedisplayinfo();
}
// Wallpapers are animated based on the "real" window they
// are currently targeting.
final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
if (wallpaperAnimator.mHasLocalTransformation && wallpaperAnimator.mAnimation != null && !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
attachedTransformation = wallpaperAnimator.mTransformation;
if (DEBUG_WALLPAPER && attachedTransformation != null) {
Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
}
}
final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ? null : wallpaperTarget.mAppToken.mAppAnimator;
if (wpAppAnimator != null && wpAppAnimator.hasTransformation && wpAppAnimator.animation != null && !wpAppAnimator.animation.getDetachWallpaper()) {
appTransformation = wpAppAnimator.transformation;
if (DEBUG_WALLPAPER && appTransformation != null) {
Slog.v(TAG, "WP target app xform: " + appTransformation);
}
}
}
final int displayId = mWin.getDisplayId();
final ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId);
final boolean screenAnimation = screenRotationAnimation != null && screenRotationAnimation.isAnimating();
float ratio = 1.0f;
float pendingX = 0.0f;
float pendingY = 0.0f;
if (type == TYPE_LEFT) {
ratio = mSingleHandScale;
pendingY = (float) mHeight * (1 - mSingleHandScale);
} else if (type == TYPE_RIGHT) {
ratio = mSingleHandScale;
pendingX = (float) mWidth * (1 - mSingleHandScale);
pendingY = (float) mHeight * (1 - mSingleHandScale);
}
mHasClipRect = false;
if (selfTransformation || attachedTransformation != null || appTransformation != null || screenAnimation) {
// cache often used attributes locally
final Rect frame = mWin.mFrame;
final float[] tmpFloats = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
// Compute the desired transformation.
if (screenAnimation && screenRotationAnimation.isRotating()) {
// If we are doing a screen animation, the global rotation
// applied to windows can result in windows that are carefully
// aligned with each other to slightly separate, allowing you
// to see what is behind them. An unsightly mess. This...
// thing... magically makes it call good: scale each window
// slightly (two pixels larger in each dimension, from the
// window's center).
final float w = frame.width();
final float h = frame.height();
if (w >= 1 && h >= 1) {
tmpMatrix.setScale(1 + 2 / w, 1 + 2 / h, w / 2, h / 2);
} else {
tmpMatrix.reset();
}
} else {
tmpMatrix.reset();
}
tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
if (selfTransformation) {
tmpMatrix.postConcat(mTransformation.getMatrix());
}
if (attachedTransformation != null) {
tmpMatrix.postConcat(attachedTransformation.getMatrix());
}
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
if (screenAnimation) {
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
MagnificationSpec spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
applyMagnificationSpec(spec, tmpMatrix);
}
// "convert" it into SurfaceFlinger's format
// (a 2x2 matrix + an offset)
// Here we must not transform the position of the surface
// since it is already included in the transformation.
//Slog.i(TAG_WM, "Transform: " + matrix);
mHaveMatrix = true;
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X] * ratio;
mDtDx = tmpFloats[Matrix.MSKEW_Y] * ratio;
mDsDy = tmpFloats[Matrix.MSKEW_X] * ratio;
mDtDy = tmpFloats[Matrix.MSCALE_Y] * ratio;
float x = tmpFloats[Matrix.MTRANS_X] * ratio + pendingX;
float y = tmpFloats[Matrix.MTRANS_Y] * ratio + pendingY;
mWin.mShownPosition.set(Math.round(x), Math.round(y));
// Now set the alpha... but because our current hardware
// can't do alpha transformation on a non-opaque surface,
// turn it off if we are running an animation that is also
// transforming since it is more important to have that
// animation be smooth.
mShownAlpha = mAlpha;
if (!mService.mLimitedAlphaCompositing || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) && floatEqualCompare(x, frame.left) && floatEqualCompare(y, frame.top)))) {
//Slog.i(TAG_WM, "Applying alpha transform");
if (selfTransformation) {
mShownAlpha *= mTransformation.getAlpha();
}
if (attachedTransformation != null) {
mShownAlpha *= attachedTransformation.getAlpha();
}
if (appTransformation != null) {
mShownAlpha *= appTransformation.getAlpha();
if (appTransformation.hasClipRect()) {
mClipRect.set(appTransformation.getClipRect());
mHasClipRect = true;
// bounds to compensate for this.
if (mWin.layoutInParentFrame()) {
mClipRect.offset((mWin.mContainingFrame.left - mWin.mFrame.left), mWin.mContainingFrame.top - mWin.mFrame.top);
}
}
}
if (screenAnimation) {
mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
} else {
//Slog.i(TAG_WM, "Not applying alpha transform");
}
if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0))
Slog.v(TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") + " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) + " screen=" + (screenAnimation ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
return;
} else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
return;
} else if (mWin.isDragResizeChanged()) {
// with new geometry.
return;
}
if (WindowManagerService.localLOGV)
Slog.v(TAG, "computeShownFrameLocked: " + this + " not attached, mAlpha=" + mAlpha);
MagnificationSpec spec = null;
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
}
if (spec != null) {
final Rect frame = mWin.mFrame;
final float[] tmpFloats = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
applyMagnificationSpec(spec, tmpMatrix);
tmpMatrix.getValues(tmpFloats);
mHaveMatrix = true;
mDsDx = tmpFloats[Matrix.MSCALE_X] * ratio;
mDtDx = tmpFloats[Matrix.MSKEW_Y] * ratio;
mDsDy = tmpFloats[Matrix.MSKEW_X] * ratio;
mDtDy = tmpFloats[Matrix.MSCALE_Y] * ratio;
float x = tmpFloats[Matrix.MTRANS_X] * ratio + pendingX;
float y = tmpFloats[Matrix.MTRANS_Y] * ratio + pendingY;
mWin.mShownPosition.set(Math.round(x), Math.round(y));
mShownAlpha = mAlpha;
} else {
float x = mWin.mFrame.left * ratio + pendingX;
float y = mWin.mFrame.top * ratio + pendingY;
mWin.mShownPosition.set((int) x, (int) y);
if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
mWin.mShownPosition.offset((int) (mWin.mXOffset * mSingleHandScale), (int) (mWin.mYOffset * mSingleHandScale));
}
mShownAlpha = mAlpha;
mHaveMatrix = false;
mDsDx = mWin.mGlobalScale * ratio;
mDtDx = 0;
mDsDy = 0;
mDtDy = mWin.mGlobalScale * ratio;
}
}
use of android.view.animation.Transformation in project android_frameworks_base by DirtyUnicorns.
the class WindowStateAnimator method computeShownFrameLocked.
void computeShownFrameLocked(int type) {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation = (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation) ? mAttachedWinAnimator.mTransformation : null;
Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation) ? mAppAnimator.transformation : null;
if (type == TYPE_LEFT || type == TYPE_RIGHT) {
updatedisplayinfo();
}
// Wallpapers are animated based on the "real" window they
// are currently targeting.
final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
if (wallpaperAnimator.mHasLocalTransformation && wallpaperAnimator.mAnimation != null && !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
attachedTransformation = wallpaperAnimator.mTransformation;
if (DEBUG_WALLPAPER && attachedTransformation != null) {
Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
}
}
final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ? null : wallpaperTarget.mAppToken.mAppAnimator;
if (wpAppAnimator != null && wpAppAnimator.hasTransformation && wpAppAnimator.animation != null && !wpAppAnimator.animation.getDetachWallpaper()) {
appTransformation = wpAppAnimator.transformation;
if (DEBUG_WALLPAPER && appTransformation != null) {
Slog.v(TAG, "WP target app xform: " + appTransformation);
}
}
}
final int displayId = mWin.getDisplayId();
final ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId);
final boolean screenAnimation = screenRotationAnimation != null && screenRotationAnimation.isAnimating();
float ratio = 1.0f;
float pendingX = 0.0f;
float pendingY = 0.0f;
if (type == TYPE_LEFT) {
ratio = mSingleHandScale;
pendingY = (float) mHeight * (1 - mSingleHandScale);
} else if (type == TYPE_RIGHT) {
ratio = mSingleHandScale;
pendingX = (float) mWidth * (1 - mSingleHandScale);
pendingY = (float) mHeight * (1 - mSingleHandScale);
}
mHasClipRect = false;
if (selfTransformation || attachedTransformation != null || appTransformation != null || screenAnimation) {
// cache often used attributes locally
final Rect frame = mWin.mFrame;
final float[] tmpFloats = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
// Compute the desired transformation.
if (screenAnimation && screenRotationAnimation.isRotating()) {
// If we are doing a screen animation, the global rotation
// applied to windows can result in windows that are carefully
// aligned with each other to slightly separate, allowing you
// to see what is behind them. An unsightly mess. This...
// thing... magically makes it call good: scale each window
// slightly (two pixels larger in each dimension, from the
// window's center).
final float w = frame.width();
final float h = frame.height();
if (w >= 1 && h >= 1) {
tmpMatrix.setScale(1 + 2 / w, 1 + 2 / h, w / 2, h / 2);
} else {
tmpMatrix.reset();
}
} else {
tmpMatrix.reset();
}
tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
if (selfTransformation) {
tmpMatrix.postConcat(mTransformation.getMatrix());
}
if (attachedTransformation != null) {
tmpMatrix.postConcat(attachedTransformation.getMatrix());
}
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
// The translation that applies the position of the window needs to be applied at the
// end in case that other translations include scaling. Otherwise the scaling will
// affect this translation. But it needs to be set before the screen rotation animation
// so the pivot point is at the center of the screen for all windows.
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
if (screenAnimation) {
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
MagnificationSpec spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
applyMagnificationSpec(spec, tmpMatrix);
}
// "convert" it into SurfaceFlinger's format
// (a 2x2 matrix + an offset)
// Here we must not transform the position of the surface
// since it is already included in the transformation.
//Slog.i(TAG_WM, "Transform: " + matrix);
mHaveMatrix = true;
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X] * ratio;
mDtDx = tmpFloats[Matrix.MSKEW_Y] * ratio;
mDsDy = tmpFloats[Matrix.MSKEW_X] * ratio;
mDtDy = tmpFloats[Matrix.MSCALE_Y] * ratio;
float x = tmpFloats[Matrix.MTRANS_X] * ratio + pendingX;
float y = tmpFloats[Matrix.MTRANS_Y] * ratio + pendingY;
mWin.mShownPosition.set(Math.round(x), Math.round(y));
// Now set the alpha... but because our current hardware
// can't do alpha transformation on a non-opaque surface,
// turn it off if we are running an animation that is also
// transforming since it is more important to have that
// animation be smooth.
mShownAlpha = mAlpha;
if (!mService.mLimitedAlphaCompositing || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) && floatEqualCompare(x, frame.left) && floatEqualCompare(y, frame.top)))) {
//Slog.i(TAG_WM, "Applying alpha transform");
if (selfTransformation) {
mShownAlpha *= mTransformation.getAlpha();
}
if (attachedTransformation != null) {
mShownAlpha *= attachedTransformation.getAlpha();
}
if (appTransformation != null) {
mShownAlpha *= appTransformation.getAlpha();
if (appTransformation.hasClipRect()) {
mClipRect.set(appTransformation.getClipRect());
mHasClipRect = true;
// bounds to compensate for this.
if (mWin.layoutInParentFrame()) {
mClipRect.offset((mWin.mContainingFrame.left - mWin.mFrame.left), mWin.mContainingFrame.top - mWin.mFrame.top);
}
}
}
if (screenAnimation) {
mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
} else {
//Slog.i(TAG_WM, "Not applying alpha transform");
}
if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0))
Slog.v(TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") + " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) + " screen=" + (screenAnimation ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
return;
} else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
return;
} else if (mWin.isDragResizeChanged()) {
// with new geometry.
return;
}
if (WindowManagerService.localLOGV)
Slog.v(TAG, "computeShownFrameLocked: " + this + " not attached, mAlpha=" + mAlpha);
MagnificationSpec spec = null;
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
}
if (spec != null) {
final Rect frame = mWin.mFrame;
final float[] tmpFloats = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
applyMagnificationSpec(spec, tmpMatrix);
tmpMatrix.getValues(tmpFloats);
mHaveMatrix = true;
mDsDx = tmpFloats[Matrix.MSCALE_X] * ratio;
mDtDx = tmpFloats[Matrix.MSKEW_Y] * ratio;
mDsDy = tmpFloats[Matrix.MSKEW_X] * ratio;
mDtDy = tmpFloats[Matrix.MSCALE_Y] * ratio;
float x = tmpFloats[Matrix.MTRANS_X] * ratio + pendingX;
float y = tmpFloats[Matrix.MTRANS_Y] * ratio + pendingY;
mWin.mShownPosition.set(Math.round(x), Math.round(y));
mShownAlpha = mAlpha;
} else {
float x = mWin.mFrame.left * ratio + pendingX;
float y = mWin.mFrame.top * ratio + pendingY;
mWin.mShownPosition.set((int) x, (int) y);
if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
mWin.mShownPosition.offset((int) (mWin.mXOffset * mSingleHandScale), (int) (mWin.mYOffset * mSingleHandScale));
}
mShownAlpha = mAlpha;
mHaveMatrix = false;
mDsDx = mWin.mGlobalScale * ratio;
mDtDx = 0;
mDsDy = 0;
mDtDy = mWin.mGlobalScale * ratio;
}
}
use of android.view.animation.Transformation in project android_frameworks_base by AOSPA.
the class View method setDisplayListProperties.
/**
* This method is called by getDisplayList() when a display list is recorded for a View.
* It pushes any properties to the RenderNode that aren't managed by the RenderNode.
*/
void setDisplayListProperties(RenderNode renderNode) {
if (renderNode != null) {
renderNode.setHasOverlappingRendering(getHasOverlappingRendering());
renderNode.setClipToBounds(mParent instanceof ViewGroup && ((ViewGroup) mParent).getClipChildren());
float alpha = 1;
if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
ViewGroup parentVG = (ViewGroup) mParent;
final Transformation t = parentVG.getChildTransformation();
if (parentVG.getChildStaticTransformation(this, t)) {
final int transformType = t.getTransformationType();
if (transformType != Transformation.TYPE_IDENTITY) {
if ((transformType & Transformation.TYPE_ALPHA) != 0) {
alpha = t.getAlpha();
}
if ((transformType & Transformation.TYPE_MATRIX) != 0) {
renderNode.setStaticMatrix(t.getMatrix());
}
}
}
}
if (mTransformationInfo != null) {
alpha *= getFinalAlpha();
if (alpha < 1) {
final int multipliedAlpha = (int) (255 * alpha);
if (onSetAlpha(multipliedAlpha)) {
alpha = 1;
}
}
renderNode.setAlpha(alpha);
} else if (alpha < 1) {
renderNode.setAlpha(alpha);
}
}
}
use of android.view.animation.Transformation in project platform_frameworks_base by android.
the class ViewGroup_Delegate method transformCanvas.
// Copied from android.view.View#draw(Canvas, ViewGroup, long) and removed code paths
// which were never taken. Ideally, we should hook up the shadow code in the same method so
// that we don't have to transform the canvas twice.
private static int transformCanvas(ViewGroup thisVG, Canvas canvas, View child) {
final int restoreTo = canvas.save();
final boolean childHasIdentityMatrix = child.hasIdentityMatrix();
int flags = thisVG.mGroupFlags;
Transformation transformToApply = null;
boolean concatMatrix = false;
if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
final Transformation t = thisVG.getChildTransformation();
final boolean hasTransform = thisVG.getChildStaticTransformation(child, t);
if (hasTransform) {
final int transformType = t.getTransformationType();
transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
}
}
concatMatrix |= childHasIdentityMatrix;
child.computeScroll();
int sx = child.mScrollX;
int sy = child.mScrollY;
canvas.translate(child.mLeft - sx, child.mTop - sy);
float alpha = child.getAlpha() * child.getTransitionAlpha();
if (transformToApply != null || alpha < 1 || !childHasIdentityMatrix) {
if (transformToApply != null || !childHasIdentityMatrix) {
int transX = -sx;
int transY = -sy;
if (transformToApply != null) {
if (concatMatrix) {
// Undo the scroll translation, apply the transformation matrix,
// then redo the scroll translate to get the correct result.
canvas.translate(-transX, -transY);
canvas.concat(transformToApply.getMatrix());
canvas.translate(transX, transY);
}
if (!childHasIdentityMatrix) {
canvas.translate(-transX, -transY);
canvas.concat(child.getMatrix());
canvas.translate(transX, transY);
}
}
}
}
return restoreTo;
}
Aggregations