I am trying to write an animation like in WhatsApp Call screen. But I don't know what is the true way to achieve this.
To achieve this animation I am starting trying with fadein and fadeout animation. These are my set methods for fade in and out animations.
private Animation setAnimFadeOut(int startOff,int duration){
Animation animFadeOut;
animFadeOut = new AlphaAnimation(1, 0);
animFadeOut.setInterpolator(new AccelerateInterpolator());
animFadeOut.setStartOffset(startOff);
animFadeOut.setDuration(duration);
return animFadeOut;
}
private Animation setAnimFadeIn(int startOff,int duration){
Animation animFadeIn;
animFadeIn = new AlphaAnimation(0, 1);
animFadeIn.setInterpolator(new AccelerateInterpolator());
animFadeIn.setStartOffset(startOff);
animFadeIn.setDuration(duration);
return animFadeIn;
}
and for every animations animationlisteners onAnimationEnd method triggers animation for restart. fadeIn animation starts fadeOut animation and fadeOut starts fadeIn animation.
right1FadeOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
right1.startAnimation(right1FadeIn);
Log.i(TAG, "onAnimationEnd: 1 outEnd");
}
});
right1FadeIn.setAnimationListener(new Animation.AnimationListener() {
Override
public void onAnimationEnd(Animation animation) {
right1.startAnimation(right1FadeOut);
Log.i(TAG, "onAnimationEnd: 1 inEnd");
}
});
Initialization
int startOff = 0;
int diff = 100;
int duration = 600;
final Animation right1FadeOut = setAnimFadeOut(startOff,duration);
final Animation right1FadeIn = setAnimFadeIn(0,duration);
final Animation right2FadeOut = setAnimFadeOut(startOff+diff,duration+diff);
final Animation right2FadeIn = setAnimFadeIn(0,duration);
final Animation right3FadeOut = setAnimFadeOut(startOff+diff*2,duration+diff*2);
final Animation right3FadeIn = setAnimFadeIn(0,duration);
I am starting animation calling fadeout for every button and it did not work as I expected. How can I achieve animation like WhatsApp?
right1.startAnimation(right1FadeOut);
right2.startAnimation(right2FadeOut);
right3.startAnimation(right3FadeOut);
this is the result.
I would first use Animator objects instead of Animation, then i can use AnimatorSet to control all animators as a group. (aka: order)
For example:
activity XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="@drawable/ic_launcher_foreground" />
<ImageView
android:id="@+id/img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="@drawable/ic_launcher_foreground" />
<ImageView
android:id="@+id/img3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="@drawable/ic_launcher_foreground" />
<ImageView
android:id="@+id/img4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="@drawable/ic_launcher_foreground" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Activity Class:
Java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View[] images = {findViewById(R.id.img1), findViewById(R.id.img2), findViewById(R.id.img3), findViewById(R.id.img4),}; //array of views that we want to animate
//we will have 2 animator foreach view, fade in & fade out
//prepare animators - creating array of animators & instantiating Object animators
ArrayList<ObjectAnimator> anims = new ArrayList<>(images.length * 2);
for (View v : images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f).setDuration(80)); //fade in animator
for (View v : images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 1f, 0f).setDuration(80)); //fade out animator
final AnimatorSet set = new AnimatorSet(); //create Animator set object
//if we want to repeat the animations then we set listener to start again in 'onAnimationEnd' method
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
set.start(); //repeat animator set indefinitely
}
});
set.setStartDelay(600); //set delay every time we start the chain of animations
for (int i = 0; i < anims.size() - 1; i++) set.play(anims.get(i)).before(anims.get(i + 1)); //put all animations in set by order (from first to last)
findViewById(R.id.txt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //start the animations on click
set.start();
}
});
}
}
Kotlin:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val images = arrayOf(img1, img2, img3, img4) //array of views that we want to animate
//we will have 2 animator foreach view, fade in & fade out
//prepare animators - creating array of animators & instantiating Object animators
val anims = ArrayList<ObjectAnimator>(images.size * 2)
for (v in images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f).setDuration(80)) //fade in animator
for (v in images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 1f, 0f).setDuration(80)) //fade out animator
val set = AnimatorSet() //create Animator set object
//if we want to repeat the animations then we set listener to start again in 'onAnimationEnd' method
set.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) = set.start() //repeat animator set indefinitely
})
set.startDelay = 600 //set delay every time we start the chain of animations
for (i in 0 until anims.size - 1) set.play(anims[i]).before(anims[i + 1]) //put all animations in set by order (from first to last)
txt.setOnClickListener { set.start() } //start the animations on click
}
}
Try to start your subsequent animations in your AnimationListener
s onAnimationStart
method with an increasing delay.
arrow1FadeIn.setAnimationListener( new Animation.AnimationListener() {
@Override
public void onAnimationStart( Animation animation )
{
arrow2.startAnimation( arrow2FadeIn );
}
@Override
public void onAnimationEnd( Animation animation )
{
arrow1.startAnimation( arrow1FadeOut );
}
@Override
public void onAnimationRepeat( Animation animation )
{
}
} );
arrow1FadeOut.setAnimationListener( new Animation.AnimationListener()
{
@Override
public void onAnimationStart( Animation animation )
{
}
@Override
public void onAnimationEnd( Animation animation )
{
arrow1.startAnimation( arrow1FadeIn );
}
@Override
public void onAnimationRepeat( Animation animation )
{
}
} );
And your animations like
final Animation arrow1FadeIn = setAnimFadeIn( startOff, duration );
final Animation arrow1FadeOut = setAnimFadeOut( startOff, duration );
final Animation arrow2FadeIn = setAnimFadeIn( diff, duration );
final Animation arrow2FadeOut = setAnimFadeOut( startOff, duration );
final Animation arrow3FadeIn = setAnimFadeIn( diff*2, duration );
final Animation arrow3FadeOut = setAnimFadeOut( startOff, duration );
You may need to twiddle a bit when starting all over again but this way, they should be in sync. Just start the first fadeIn Animation with
arrow1.startAnimation( arrow1FadeIn );
I suggest you use Facebook Rebound library .
It support Spring
animation like facebook has. It also has cool feature called SpringChain
, which automatically play a sequence of animation using Spring physics from start to end. You can custom how you want to animate the View (scale, alpha, translate ...)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.