I've made a custom view for visualizes the progress. It has a simple intro animation like the below :
PropertyValuesHolder c=PropertyValuesHolder.ofInt("c",0,100);
ValueAnimator anim=new ValueAnimator();
anim.setValues(c);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
position = (int) animation.getAnimatedValue("c");
postInvalidate();
}
});
anim.setDuration(1000);
anim.start();
It works smoothly with about 50 keyframes, but after the AdView that placed on the parent view, turns visible the same animation runs with lags (performance reduced to about 20 keyframes). I check the ValueAnimator.FrameDelay, it doesn't change.
What causes this problem, And what is the solution?
As #MartinMarconcini said, the problem related to the WebView that embedded inside the AdView. The performance improved by enabling Hardware Acceleration on the AdView.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
adView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
else adView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Related
We need to have an animation to push the title bar view out of the screen and pull it into the screen. The title bar locates on top of the screen.
To do this specific animation will cost a lot for the screen that the animation is not smooth. I implement is in this way:
ValueAnimator animDown = ValueAnimator.ofFloat(1f, 0f);
animDown.setDuration(300);
params = (RelativeLayout.LayoutParams) titleView.getLayoutParams();
animDown.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
newHeight = -(int) (titleView.getHeight() * currentValue);
if (newHeight != lastHeight) {
params.setMargins(0, newHeight, 0, 0);
titleView.requestLayout();
}
lastHeight = newHeight;
}
});
this works fine in some places but not here, for I found that the callback method onAnimationUpdate is called very few times (say 6-8 times) during the animation, which means one frame update cost over 40ms, which looks too laggy.
My question is: is there a way to increase the frequency of the callback method onAnimationUpdate, or is there any other way to do this animation more smoothly?
Previously we are using other animations such as fade out and it works well, but push out animation here cost too much while the grid view list below the title view also is quite heavy.
i am making an android app and i am a newbie in development.
I created a startup animation for the app, using the app icon that is scaled from O% size to 100% size and rotated at the same time. This works allright. But i have a problem with it. In xml, the view visibility is set to gone initially. In code, i call image.setVisibility(View.VISIBLE) and then image.startAnimation(iconAnimation) . But the result is that i can see a flash of the ImageView before it starts animating, for like half a second or so. You can see the gif.
Gif:
see the gif
Can you help me with this? Thanks in advance.
My code:
runOnUiThread(new Runnable() {
#Override
public void run() {
// here
image.setVisibility(View.VISIBLE);
image.startAnimation(imageAnim);
//also found this somewhere, didn't help.
image.invalidate();
}
});
Layout xml:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35sp"
android:text="Kytky"
android:layout_centerInParent="true"
android:id="#+id/welcome_text"
android:visibility="gone"/>
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#mipmap/ic_launcher"
android:layout_centerInParent="true"
android:id="#+id/welcome_image"
android:visibility="gone"/>
You can use value animator instead, You can hack through the animation
imageView.setPivotX(viewCenterX);
imageView.setPivotY(viewCenterY);
imageView.setScaleX(0);
imageView.setScaleY(0);
final FloatEvaluator scaleEvaluator = new FloatEvaluator();
final FloatEvaluator rotationEvaluator = new FloatEvaluator();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
valueAnimator.setDuration(TimeUnit.SECONDS.toMillis(1));
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = animation.getAnimatedFraction();
float scale = scaleEvaluator.evaluate(fraction, 0f, 1f);
float rotation = rotationEvaluator.evaluate(fraction, 0f, 360f);
imageView.setScale(scale);
imageView.setRotation(rotation);
}
});
valueAnimator.start();
Start one more animator or use this same animator to slide the logo up. Using this animators you will have full control over your animation.
you can switch the view visibility when the animations starts
imageAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
image.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
image.startAnimation(imageAnim);
the blink happens because the view visibility far from starting the animations, so in the first frame it will have its real size, and after that starts the animation
You need to work with alpha as well...make it visible and set alpha to minimum value than set alpha gradually to maximum value with in handler.
I have an Activity with a toolbar (which is part of the SharedElements Activity entering animation) and below that toolbar are three ImageViews horizontally next to each other. In their XML implementation all three are set INVISIBLE.
What I'm trying to do is, to animate them sequentially "dropping" from behind the toolbar. My implemenation is this:
int delay = 500;
for (int y = 0; y < 3; y++) {
ObjectAnimator oa = ObjectAnimator.ofFloat(imageViews[y],
"translationY", -300, 0);
oa.setDuration(600);
oa.setStartDelay(delay);
oa.start();
imageViews[y].setVisibility(View.VISIBLE);
delay = delay+100;
}
}
As you can see, I'm iterating through the three ImageViews and start a animation for each one to go from a -300 X-position (which is behind the toolbar) to their normal position.
This animation works great - just as I want it to be, but the problem is, that right before all ImageViews are briefly flickering which I can't explain. I tried debugging, but while I'm going through the lines of that part my screen stays black. So I can't determine where/why the Views become visible.
Maybe you can help me to find my mistake.
Thank you, this is my working Code:
For all three ImageViews:
ObjectAnimator anim1Pin = ObjectAnimator.ofFloat(img_pinned, "translationY", -300, 0);
anim1Pin.setDuration(ANIMATON_DURATION);
anim1Pin.setStartDelay(300);
anim1Pin.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
img_pinned.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
And the AnimatorSet:
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(anim1Pin, anim2Alarm, anim3LED);
animatorSet.start();
Few things, first, the problem may be as simple as setting the visiblity state to GONE and then after animation starts, setting it to visible. However, I would also use AnimatorSet to play the animations together and add the delay rather than do it in a loop.
If you use AnimatorSet there is an onAnimationStart method in AnimationListener that you can use the set the visible to VISIBLE rather than do it how you have to ensure that they become visible at the right time.
I am a beginner in Android development.
Coming from iOS background I tend to use animations on Views
to animate a View in Android. I have found out to do it in a "normal" way
For example to animate alpha value of a view
valueAnimator = ValueAnimator.ofFloat(0, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
viewToAnimate.alpha(value);
}
});
valueAnimator.setDuration(10000);
valueAnimator.start();
I am wondering if there is an easy way. Perhaps create a "Helper" class to animate an objects alpha value. Where we can pass in the View to animate and have it animated.
Something like AnimationHelper.animateAlpha(viewToAnimate, OF_VALUE, TO_VALUE, DURATION);
I am sorry to ask this question. Since my Java knowledge is rusty, I am wondering if there is any kind folks out there who is willing to help out.
Thank you
Try this:
viewToAnimate.animate().alpha(TO_VALUE).setDuration(DURATION);
or this:
ObjectAnimator anim = ObjectAnimator.ofFloat(viewToAnimate, "alpha", FROM_VALUE, TO_VALUE);
anim.setDuration(DURATION);
anim.start();
Since API16 ImageView.setImageAlpha(int) should be used instead of View.setAlpha(float) for better performance.
But how can I animate that value? I tried ValueAnimator without success.
ObjectAnimator.ofInt(imageView, "imageAlpha", 0).start();
I mean what Chet Haase is talking about here http://youtu.be/vQZFaec9NpA?t=33m
It should be fine. Maybe you forgot to specify the animation duration, or your alpha values are wrong (negative, too small, too close to notice)?
You can always animate using custom listener. It's longer, but easier to debug:
ValueAnimator animator = ValueAnimator.ofInt(0,255);
animator.setDuration(300);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
imageView.setImageAlpha(valueAnimator.getAnimatedValue());
}
});
animator.start();