use of android.view.animation.Transformation in project android_frameworks_base by ParanoidAndroid.
the class View method draw.
/**
* This method is called by ViewGroup.drawChild() to have each child view draw itself.
* This draw() method is an implementation detail and is not intended to be overridden or
* to be called from anywhere else other than ViewGroup.drawChild().
*/
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
boolean useDisplayListProperties = mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
boolean more = false;
final boolean childHasIdentityMatrix = hasIdentityMatrix();
final int flags = parent.mGroupFlags;
if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) {
parent.mChildTransformation.clear();
parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
Transformation transformToApply = null;
boolean concatMatrix = false;
boolean scalingRequired = false;
boolean caching;
int layerType = getLayerType();
final boolean hardwareAccelerated = canvas.isHardwareAccelerated();
if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 || (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
caching = true;
// Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
if (mAttachInfo != null)
scalingRequired = mAttachInfo.mScalingRequired;
} else {
caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
}
final Animation a = getAnimation();
if (a != null) {
more = drawAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
if (concatMatrix) {
mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
transformToApply = parent.mChildTransformation;
} else {
if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) == PFLAG3_VIEW_IS_ANIMATING_TRANSFORM && mDisplayList != null) {
// No longer animating: clear out old animation matrix
mDisplayList.setAnimationMatrix(null);
mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
if (!useDisplayListProperties && (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
final boolean hasTransform = parent.getChildStaticTransformation(this, parent.mChildTransformation);
if (hasTransform) {
final int transformType = parent.mChildTransformation.getTransformationType();
transformToApply = transformType != Transformation.TYPE_IDENTITY ? parent.mChildTransformation : null;
concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
}
}
}
concatMatrix |= !childHasIdentityMatrix;
// Sets the flag as early as possible to allow draw() implementations
// to call invalidate() successfully when doing animations
mPrivateFlags |= PFLAG_DRAWN;
if (!concatMatrix && (flags & (ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS | ViewGroup.FLAG_CLIP_CHILDREN)) == ViewGroup.FLAG_CLIP_CHILDREN && canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) && (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;
return more;
}
mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED;
if (hardwareAccelerated) {
// Clear INVALIDATED flag to allow invalidation to occur during rendering, but
// retain the flag's value temporarily in the mRecreateDisplayList flag
mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) == PFLAG_INVALIDATED;
mPrivateFlags &= ~PFLAG_INVALIDATED;
}
DisplayList displayList = null;
Bitmap cache = null;
boolean hasDisplayList = false;
if (caching) {
if (!hardwareAccelerated) {
if (layerType != LAYER_TYPE_NONE) {
layerType = LAYER_TYPE_SOFTWARE;
buildDrawingCache(true);
}
cache = getDrawingCache(true);
} else {
switch(layerType) {
case LAYER_TYPE_SOFTWARE:
if (useDisplayListProperties) {
hasDisplayList = canHaveDisplayList();
} else {
buildDrawingCache(true);
cache = getDrawingCache(true);
}
break;
case LAYER_TYPE_HARDWARE:
if (useDisplayListProperties) {
hasDisplayList = canHaveDisplayList();
}
break;
case LAYER_TYPE_NONE:
// Delay getting the display list until animation-driven alpha values are
// set up and possibly passed on to the view
hasDisplayList = canHaveDisplayList();
break;
}
}
}
useDisplayListProperties &= hasDisplayList;
if (useDisplayListProperties) {
displayList = getDisplayList();
if (!displayList.isValid()) {
// Uncommon, but possible. If a view is removed from the hierarchy during the call
// to getDisplayList(), the display list will be marked invalid and we should not
// try to use it again.
displayList = null;
hasDisplayList = false;
useDisplayListProperties = false;
}
}
int sx = 0;
int sy = 0;
if (!hasDisplayList) {
computeScroll();
sx = mScrollX;
sy = mScrollY;
}
final boolean hasNoCache = cache == null || hasDisplayList;
final boolean offsetForScroll = cache == null && !hasDisplayList && layerType != LAYER_TYPE_HARDWARE;
int restoreTo = -1;
if (!useDisplayListProperties || transformToApply != null) {
restoreTo = canvas.save();
}
if (offsetForScroll) {
canvas.translate(mLeft - sx, mTop - sy);
} else {
if (!useDisplayListProperties) {
canvas.translate(mLeft, mTop);
}
if (scalingRequired) {
if (useDisplayListProperties) {
// TODO: Might not need this if we put everything inside the DL
restoreTo = canvas.save();
}
// mAttachInfo cannot be null, otherwise scalingRequired == false
final float scale = 1.0f / mAttachInfo.mApplicationScale;
canvas.scale(scale, scale);
}
}
float alpha = useDisplayListProperties ? 1 : getAlpha();
if (transformToApply != null || alpha < 1 || !hasIdentityMatrix() || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
if (transformToApply != null || !childHasIdentityMatrix) {
int transX = 0;
int transY = 0;
if (offsetForScroll) {
transX = -sx;
transY = -sy;
}
if (transformToApply != null) {
if (concatMatrix) {
if (useDisplayListProperties) {
displayList.setAnimationMatrix(transformToApply.getMatrix());
} else {
// 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);
}
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
float transformAlpha = transformToApply.getAlpha();
if (transformAlpha < 1) {
alpha *= transformAlpha;
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
}
if (!childHasIdentityMatrix && !useDisplayListProperties) {
canvas.translate(-transX, -transY);
canvas.concat(getMatrix());
canvas.translate(transX, transY);
}
}
// Deal with alpha if it is or used to be <1
if (alpha < 1 || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
if (alpha < 1) {
mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;
} else {
mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;
}
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
if (hasNoCache) {
final int multipliedAlpha = (int) (255 * alpha);
if (!onSetAlpha(multipliedAlpha)) {
int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 || layerType != LAYER_TYPE_NONE) {
layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
}
if (useDisplayListProperties) {
displayList.setAlpha(alpha * getAlpha());
} else if (layerType == LAYER_TYPE_NONE) {
final int scrollX = hasDisplayList ? 0 : sx;
final int scrollY = hasDisplayList ? 0 : sy;
canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft, scrollY + mBottom - mTop, multipliedAlpha, layerFlags);
}
} else {
// Alpha is handled by the child directly, clobber the layer's alpha
mPrivateFlags |= PFLAG_ALPHA_SET;
}
}
}
} else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
onSetAlpha(255);
mPrivateFlags &= ~PFLAG_ALPHA_SET;
}
if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN && !useDisplayListProperties && cache == null) {
if (offsetForScroll) {
canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop));
} else {
if (!scalingRequired || cache == null) {
canvas.clipRect(0, 0, mRight - mLeft, mBottom - mTop);
} else {
canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
}
}
}
if (!useDisplayListProperties && hasDisplayList) {
displayList = getDisplayList();
if (!displayList.isValid()) {
// Uncommon, but possible. If a view is removed from the hierarchy during the call
// to getDisplayList(), the display list will be marked invalid and we should not
// try to use it again.
displayList = null;
hasDisplayList = false;
}
}
if (hasNoCache) {
boolean layerRendered = false;
if (layerType == LAYER_TYPE_HARDWARE && !useDisplayListProperties) {
final HardwareLayer layer = getHardwareLayer();
if (layer != null && layer.isValid()) {
mLayerPaint.setAlpha((int) (alpha * 255));
((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, mLayerPaint);
layerRendered = true;
} else {
final int scrollX = hasDisplayList ? 0 : sx;
final int scrollY = hasDisplayList ? 0 : sy;
canvas.saveLayer(scrollX, scrollY, scrollX + mRight - mLeft, scrollY + mBottom - mTop, mLayerPaint, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
}
}
if (!layerRendered) {
if (!hasDisplayList) {
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchDraw(canvas);
} else {
draw(canvas);
}
} else {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags);
}
}
} else if (cache != null) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
Paint cachePaint;
if (layerType == LAYER_TYPE_NONE) {
cachePaint = parent.mCachePaint;
if (cachePaint == null) {
cachePaint = new Paint();
cachePaint.setDither(false);
parent.mCachePaint = cachePaint;
}
if (alpha < 1) {
cachePaint.setAlpha((int) (alpha * 255));
parent.mGroupFlags |= ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE;
} else if ((flags & ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE) != 0) {
cachePaint.setAlpha(255);
parent.mGroupFlags &= ~ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE;
}
} else {
cachePaint = mLayerPaint;
cachePaint.setAlpha((int) (alpha * 255));
}
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
}
if (restoreTo >= 0) {
canvas.restoreToCount(restoreTo);
}
if (a != null && !more) {
if (!hardwareAccelerated && !a.getFillAfter()) {
onSetAlpha(255);
}
parent.finishAnimatingView(this, a);
}
if (more && hardwareAccelerated) {
// invalidation is the trigger to recreate display lists, so if we're using
// display lists to render, force an invalidate to allow the animation to
// continue drawing another frame
parent.invalidate(true);
if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
// alpha animations should cause the child to recreate its display list
invalidate(true);
}
}
mRecreateDisplayList = false;
return more;
}
use of android.view.animation.Transformation in project android_frameworks_base by ParanoidAndroid.
the class WindowStateAnimator method computeShownFrameLocked.
void computeShownFrameLocked() {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation = (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation) ? mAttachedWinAnimator.mTransformation : null;
Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation) ? mAppAnimator.transformation : null;
// are currently targeting.
if (mIsWallpaper && mService.mLowerWallpaperTarget == null && mService.mWallpaperTarget != null) {
final WindowStateAnimator wallpaperAnimator = mService.mWallpaperTarget.mWinAnimator;
if (wallpaperAnimator.mHasLocalTransformation && wallpaperAnimator.mAnimation != null && !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
attachedTransformation = wallpaperAnimator.mTransformation;
if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
}
}
final AppWindowAnimator wpAppAnimator = mAnimator.getWallpaperAppAnimator();
if (wpAppAnimator != null && wpAppAnimator.hasTransformation && wpAppAnimator.animation != null && !wpAppAnimator.animation.getDetachWallpaper()) {
appTransformation = wpAppAnimator.transformation;
if (WindowManagerService.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();
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());
}
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
if (attachedTransformation != null) {
tmpMatrix.postConcat(attachedTransformation.getMatrix());
}
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
if (mAnimator.mUniverseBackground != null) {
tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
}
if (screenAnimation) {
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mDisplayMagnifier != null && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
MagnificationSpec spec = mService.mDisplayMagnifier.getMagnificationSpecForWindowLocked(mWin);
if (spec != null && !spec.isNop()) {
tmpMatrix.postScale(spec.scale, spec.scale);
tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
}
}
// "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, "Transform: " + matrix);
mHaveMatrix = true;
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_Y];
mDsDy = tmpFloats[Matrix.MSKEW_X];
mDtDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
int w = frame.width();
int h = frame.height();
mWin.mShownFrame.set(x, y, x + w, y + h);
// 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) && x == frame.left && y == frame.top))) {
//Slog.i(TAG, "Applying alpha transform");
if (selfTransformation) {
mShownAlpha *= mTransformation.getAlpha();
}
if (attachedTransformation != null) {
mShownAlpha *= attachedTransformation.getAlpha();
}
if (appTransformation != null) {
mShownAlpha *= appTransformation.getAlpha();
}
if (mAnimator.mUniverseBackground != null) {
mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
}
if (screenAnimation) {
mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
} else {
//Slog.i(TAG, "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.mInnerFields.mWallpaperActionPending) {
return;
}
if (WindowManagerService.localLOGV)
Slog.v(TAG, "computeShownFrameLocked: " + this + " not attached, mAlpha=" + mAlpha);
final boolean applyUniverseTransformation = (mAnimator.mUniverseBackground != null && mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);
MagnificationSpec spec = null;
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mDisplayMagnifier != null && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
spec = mService.mDisplayMagnifier.getMagnificationSpecForWindowLocked(mWin);
}
if (applyUniverseTransformation || 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);
if (applyUniverseTransformation) {
tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
}
if (spec != null && !spec.isNop()) {
tmpMatrix.postScale(spec.scale, spec.scale);
tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
}
tmpMatrix.getValues(tmpFloats);
mHaveMatrix = true;
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_Y];
mDsDy = tmpFloats[Matrix.MSKEW_X];
mDtDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
int w = frame.width();
int h = frame.height();
mWin.mShownFrame.set(x, y, x + w, y + h);
mShownAlpha = mAlpha;
if (applyUniverseTransformation) {
mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
}
} else {
mWin.mShownFrame.set(mWin.mFrame);
if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
}
mShownAlpha = mAlpha;
mHaveMatrix = false;
mDsDx = mWin.mGlobalScale;
mDtDx = 0;
mDsDy = 0;
mDtDy = mWin.mGlobalScale;
}
}
use of android.view.animation.Transformation in project android_frameworks_base by ParanoidAndroid.
the class WindowManagerService method setUniverseTransformLocked.
public void setUniverseTransformLocked(WindowState window, float alpha, float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
Transformation transform = window.mWinAnimator.mUniverseTransform;
transform.setAlpha(alpha);
Matrix matrix = transform.getMatrix();
matrix.getValues(mTmpFloats);
mTmpFloats[Matrix.MTRANS_X] = offx;
mTmpFloats[Matrix.MTRANS_Y] = offy;
mTmpFloats[Matrix.MSCALE_X] = dsdx;
mTmpFloats[Matrix.MSKEW_Y] = dtdx;
mTmpFloats[Matrix.MSKEW_X] = dsdy;
mTmpFloats[Matrix.MSCALE_Y] = dtdy;
matrix.setValues(mTmpFloats);
final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
final RectF dispRect = new RectF(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
matrix.mapRect(dispRect);
window.mGivenTouchableRegion.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
window.mGivenTouchableRegion.op((int) dispRect.left, (int) dispRect.top, (int) dispRect.right, (int) dispRect.bottom, Region.Op.DIFFERENCE);
window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
window.mDisplayContent.layoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
use of android.view.animation.Transformation in project HoloEverywhere by Prototik.
the class ProgressBar method startAnimation.
void startAnimation() {
if (getVisibility() != android.view.View.VISIBLE) {
return;
}
if (mIndeterminateDrawable instanceof Animatable) {
mShouldStartAnimationDrawable = true;
mHasAnimation = false;
} else {
mHasAnimation = true;
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
if (mTransformation == null) {
mTransformation = new Transformation();
} else {
mTransformation.clear();
}
if (mAnimation == null) {
mAnimation = new AlphaAnimation(0.0f, 1.0f);
} else {
mAnimation.reset();
}
mAnimation.setRepeatMode(mBehavior);
mAnimation.setRepeatCount(Animation.INFINITE);
mAnimation.setDuration(mDuration);
mAnimation.setInterpolator(mInterpolator);
mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
}
postInvalidate();
}
use of android.view.animation.Transformation in project Reader by TheKeeperOfPie.
the class UtilsAnimation method animateExpandWithHeight.
public static void animateExpandWithHeight(final View view, final float height, final OnAnimationEndListener listener, long duration) {
final boolean isShown = view.isShown();
Animation animation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
interpolatedTime = isShown ? 1.0f - interpolatedTime : interpolatedTime;
view.getLayoutParams().height = (int) (interpolatedTime * height);
view.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.d(TAG, "onAnimationStart");
}
@Override
public void onAnimationEnd(Animation animation) {
if (isShown) {
view.setVisibility(View.GONE);
}
view.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
view.requestLayout();
if (listener != null) {
listener.onAnimationEnd();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
if (!isShown) {
view.getLayoutParams().height = 0;
view.requestLayout();
view.setVisibility(View.VISIBLE);
}
float speed = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, view.getContext().getResources().getDisplayMetrics());
if (duration > 0) {
animation.setDuration(duration);
} else {
animation.setDuration((long) (height / speed * 2));
}
view.setVisibility(View.VISIBLE);
view.requestLayout();
view.startAnimation(animation);
view.invalidate();
}
Aggregations