use of android.view.animation.Transformation in project android_frameworks_base by ParanoidAndroid.
the class View method setDisplayListProperties.
/**
* This method is called by getDisplayList() when a display list is created or re-rendered.
* It sets or resets the current value of all properties on that display list (resetting is
* necessary when a display list is being re-created, because we need to make sure that
* previously-set transform values
*/
void setDisplayListProperties(DisplayList displayList) {
if (displayList != null) {
displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
displayList.setHasOverlappingRendering(hasOverlappingRendering());
if (mParent instanceof ViewGroup) {
displayList.setClipToBounds((((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
}
float alpha = 1;
if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
ViewGroup parentVG = (ViewGroup) mParent;
final boolean hasTransform = parentVG.getChildStaticTransformation(this, parentVG.mChildTransformation);
if (hasTransform) {
Transformation transform = parentVG.mChildTransformation;
final int transformType = parentVG.mChildTransformation.getTransformationType();
if (transformType != Transformation.TYPE_IDENTITY) {
if ((transformType & Transformation.TYPE_ALPHA) != 0) {
alpha = transform.getAlpha();
}
if ((transformType & Transformation.TYPE_MATRIX) != 0) {
displayList.setMatrix(transform.getMatrix());
}
}
}
}
if (mTransformationInfo != null) {
alpha *= mTransformationInfo.mAlpha;
if (alpha < 1) {
final int multipliedAlpha = (int) (255 * alpha);
if (onSetAlpha(multipliedAlpha)) {
alpha = 1;
}
}
displayList.setTransformationInfo(alpha, mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY, mTransformationInfo.mRotation, mTransformationInfo.mRotationX, mTransformationInfo.mRotationY, mTransformationInfo.mScaleX, mTransformationInfo.mScaleY);
if (mTransformationInfo.mCamera == null) {
mTransformationInfo.mCamera = new Camera();
mTransformationInfo.matrix3D = new Matrix();
}
displayList.setCameraDistance(mTransformationInfo.mCamera.getLocationZ());
if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == PFLAG_PIVOT_EXPLICITLY_SET) {
displayList.setPivotX(getPivotX());
displayList.setPivotY(getPivotY());
}
} else if (alpha < 1) {
displayList.setAlpha(alpha);
}
}
}
use of android.view.animation.Transformation in project android_frameworks_base by ParanoidAndroid.
the class ProgressBar method startAnimation.
/**
* <p>Start the indeterminate progress animation.</p>
*/
void startAnimation() {
if (getVisibility() != 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 AndroidTraining by mixi-inc.
the class IcsProgressBar method startAnimation.
/**
* <p>Start the indeterminate progress animation.</p>
*/
void startAnimation() {
if (getVisibility() != VISIBLE) {
return;
}
if (mIndeterminateDrawable instanceof Animatable) {
mShouldStartAnimationDrawable = true;
mAnimation = null;
} else {
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
mTransformation = new Transformation();
mAnimation = new AlphaAnimation(0.0f, 1.0f);
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 getCollapseHeightAnimationInternal.
private static Animation getCollapseHeightAnimationInternal(final View view, final long duration, @Nullable final OnAnimationEndListener callback) {
final int height = view.getHeight();
float speed = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, view.getContext().getResources().getDisplayMetrics());
if (height == 0) {
return new Animation() {
};
}
Animation animationCollapse = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime >= 0.99f) {
view.getLayoutParams().height = 0;
} else {
view.getLayoutParams().height = (int) ((1f - interpolatedTime) * height);
}
view.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
animationCollapse.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.getLayoutParams().height = 0;
view.setVisibility(View.GONE);
if (callback != null) {
callback.onAnimationEnd();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
animationCollapse.setDuration(duration > 0 ? duration : calculateDuration(height, speed));
view.setVisibility(View.VISIBLE);
return animationCollapse;
}
use of android.view.animation.Transformation in project XobotOS by xamarin.
the class ViewGroup method drawChild.
/**
* Draw one child of this View Group. This method is responsible for getting
* the canvas in the right state. This includes clipping, translating so
* that the child's scrolled origin is at 0, 0, and applying any animation
* transformations.
*
* @param canvas The canvas on which to draw the child
* @param child Who to draw
* @param drawingTime The time at which draw is occuring
* @return True if an invalidate() was issued
*/
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean more = false;
final int cl = child.mLeft;
final int ct = child.mTop;
final int cr = child.mRight;
final int cb = child.mBottom;
final boolean childHasIdentityMatrix = child.hasIdentityMatrix();
final int flags = mGroupFlags;
if ((flags & FLAG_CLEAR_TRANSFORMATION) == FLAG_CLEAR_TRANSFORMATION) {
mChildTransformation.clear();
mGroupFlags &= ~FLAG_CLEAR_TRANSFORMATION;
}
Transformation transformToApply = null;
Transformation invalidationTransform;
final Animation a = child.getAnimation();
boolean concatMatrix = false;
boolean scalingRequired = false;
boolean caching;
int layerType = mDrawLayers ? child.getLayerType() : LAYER_TYPE_NONE;
final boolean hardwareAccelerated = canvas.isHardwareAccelerated();
if ((flags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE || (flags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE) {
caching = true;
if (mAttachInfo != null)
scalingRequired = mAttachInfo.mScalingRequired;
} else {
caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
}
if (a != null) {
final boolean initialized = a.isInitialized();
if (!initialized) {
a.initialize(cr - cl, cb - ct, getWidth(), getHeight());
a.initializeInvalidateRegion(0, 0, cr - cl, cb - ct);
child.onAnimationStart();
}
more = a.getTransformation(drawingTime, mChildTransformation, scalingRequired ? mAttachInfo.mApplicationScale : 1f);
if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
if (mInvalidationTransformation == null) {
mInvalidationTransformation = new Transformation();
}
invalidationTransform = mInvalidationTransformation;
a.getTransformation(drawingTime, invalidationTransform, 1f);
} else {
invalidationTransform = mChildTransformation;
}
transformToApply = mChildTransformation;
concatMatrix = a.willChangeTransformationMatrix();
if (more) {
if (!a.willChangeBounds()) {
if ((flags & (FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE)) == FLAG_OPTIMIZE_INVALIDATE) {
mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
} else if ((flags & FLAG_INVALIDATE_REQUIRED) == 0) {
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
mPrivateFlags |= DRAW_ANIMATION;
invalidate(cl, ct, cr, cb);
}
} else {
if (mInvalidateRegion == null) {
mInvalidateRegion = new RectF();
}
final RectF region = mInvalidateRegion;
a.getInvalidateRegion(0, 0, cr - cl, cb - ct, region, invalidationTransform);
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
mPrivateFlags |= DRAW_ANIMATION;
final int left = cl + (int) region.left;
final int top = ct + (int) region.top;
invalidate(left, top, left + (int) (region.width() + .5f), top + (int) (region.height() + .5f));
}
}
} else if ((flags & FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == FLAG_SUPPORT_STATIC_TRANSFORMATIONS) {
final boolean hasTransform = getChildStaticTransformation(child, mChildTransformation);
if (hasTransform) {
final int transformType = mChildTransformation.getTransformationType();
transformToApply = transformType != Transformation.TYPE_IDENTITY ? 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
child.mPrivateFlags |= DRAWN;
if (!concatMatrix && canvas.quickReject(cl, ct, cr, cb, Canvas.EdgeType.BW) && (child.mPrivateFlags & DRAW_ANIMATION) == 0) {
return more;
}
float alpha = child.getAlpha();
// Bail out early if the view does not need to be drawn
if (alpha <= ViewConfiguration.ALPHA_THRESHOLD && (child.mPrivateFlags & ALPHA_SET) == 0 && !(child instanceof SurfaceView)) {
return more;
}
if (hardwareAccelerated) {
// Clear INVALIDATED flag to allow invalidation to occur during rendering, but
// retain the flag's value temporarily in the mRecreateDisplayList flag
child.mRecreateDisplayList = (child.mPrivateFlags & INVALIDATED) == INVALIDATED;
child.mPrivateFlags &= ~INVALIDATED;
}
child.computeScroll();
final int sx = child.mScrollX;
final int sy = child.mScrollY;
DisplayList displayList = null;
Bitmap cache = null;
boolean hasDisplayList = false;
if (caching) {
if (!hardwareAccelerated) {
if (layerType != LAYER_TYPE_NONE) {
layerType = LAYER_TYPE_SOFTWARE;
child.buildDrawingCache(true);
}
cache = child.getDrawingCache(true);
} else {
switch(layerType) {
case LAYER_TYPE_SOFTWARE:
child.buildDrawingCache(true);
cache = child.getDrawingCache(true);
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 = child.canHaveDisplayList();
break;
}
}
}
final boolean hasNoCache = cache == null || hasDisplayList;
final boolean offsetForScroll = cache == null && !hasDisplayList && layerType != LAYER_TYPE_HARDWARE;
final int restoreTo = canvas.save();
if (offsetForScroll) {
canvas.translate(cl - sx, ct - sy);
} else {
canvas.translate(cl, ct);
if (scalingRequired) {
// mAttachInfo cannot be null, otherwise scalingRequired == false
final float scale = 1.0f / mAttachInfo.mApplicationScale;
canvas.scale(scale, scale);
}
}
if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
if (transformToApply != null || !childHasIdentityMatrix) {
int transX = 0;
int transY = 0;
if (offsetForScroll) {
transX = -sx;
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);
mGroupFlags |= FLAG_CLEAR_TRANSFORMATION;
}
float transformAlpha = transformToApply.getAlpha();
if (transformAlpha < 1.0f) {
alpha *= transformToApply.getAlpha();
mGroupFlags |= FLAG_CLEAR_TRANSFORMATION;
}
}
if (!childHasIdentityMatrix) {
canvas.translate(-transX, -transY);
canvas.concat(child.getMatrix());
canvas.translate(transX, transY);
}
}
if (alpha < 1.0f) {
mGroupFlags |= FLAG_CLEAR_TRANSFORMATION;
if (hasNoCache) {
final int multipliedAlpha = (int) (255 * alpha);
if (!child.onSetAlpha(multipliedAlpha)) {
int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN || layerType != LAYER_TYPE_NONE) {
layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
}
if (layerType == LAYER_TYPE_NONE) {
final int scrollX = hasDisplayList ? 0 : sx;
final int scrollY = hasDisplayList ? 0 : sy;
canvas.saveLayerAlpha(scrollX, scrollY, scrollX + cr - cl, scrollY + cb - ct, multipliedAlpha, layerFlags);
}
} else {
// Alpha is handled by the child directly, clobber the layer's alpha
child.mPrivateFlags |= ALPHA_SET;
}
}
}
} else if ((child.mPrivateFlags & ALPHA_SET) == ALPHA_SET) {
child.onSetAlpha(255);
child.mPrivateFlags &= ~ALPHA_SET;
}
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
if (offsetForScroll) {
canvas.clipRect(sx, sy, sx + (cr - cl), sy + (cb - ct));
} else {
if (!scalingRequired || cache == null) {
canvas.clipRect(0, 0, cr - cl, cb - ct);
} else {
canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
}
}
}
if (hasDisplayList) {
displayList = child.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) {
final HardwareLayer layer = child.getHardwareLayer();
if (layer != null && layer.isValid()) {
child.mLayerPaint.setAlpha((int) (alpha * 255));
((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, child.mLayerPaint);
layerRendered = true;
} else {
final int scrollX = hasDisplayList ? 0 : sx;
final int scrollY = hasDisplayList ? 0 : sy;
canvas.saveLayer(scrollX, scrollY, scrollX + cr - cl, scrollY + cb - ct, child.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 ((child.mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
}
child.mPrivateFlags &= ~DIRTY_MASK;
child.dispatchDraw(canvas);
} else {
child.draw(canvas);
}
} else {
child.mPrivateFlags &= ~DIRTY_MASK;
((HardwareCanvas) canvas).drawDisplayList(displayList, cr - cl, cb - ct, null);
}
}
} else if (cache != null) {
child.mPrivateFlags &= ~DIRTY_MASK;
Paint cachePaint;
if (layerType == LAYER_TYPE_NONE) {
cachePaint = mCachePaint;
if (alpha < 1.0f) {
cachePaint.setAlpha((int) (alpha * 255));
mGroupFlags |= FLAG_ALPHA_LOWER_THAN_ONE;
} else if ((flags & FLAG_ALPHA_LOWER_THAN_ONE) == FLAG_ALPHA_LOWER_THAN_ONE) {
cachePaint.setAlpha(255);
mGroupFlags &= ~FLAG_ALPHA_LOWER_THAN_ONE;
}
} else {
cachePaint = child.mLayerPaint;
cachePaint.setAlpha((int) (alpha * 255));
}
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
}
canvas.restoreToCount(restoreTo);
if (a != null && !more) {
if (!hardwareAccelerated && !a.getFillAfter()) {
child.onSetAlpha(255);
}
finishAnimatingView(child, 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
invalidate(true);
if (a.hasAlpha() && (child.mPrivateFlags & ALPHA_SET) == ALPHA_SET) {
// alpha animations should cause the child to recreate its display list
child.invalidate(true);
}
}
child.mRecreateDisplayList = false;
return more;
}
Aggregations