如何制作像 whatsapp 通话屏幕这样的动画?
How can I make animation like whatsapp call screen?
我正在尝试编写类似于 WhatsApp 呼叫屏幕中的动画。但我不知道实现这一目标的真正方法是什么。
为了实现这个动画,我开始尝试淡入淡出动画。这些是我设置的淡入淡出动画的方法。
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;
}
并且对于每个动画,animationlisteners onAnimationEnd 方法都会触发动画以重新启动。 fadeIn 动画启动 fadeOut 动画,fadeOut 启动 fadeIn 动画。
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");
}
});
初始化
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);
我开始为每个按钮调用淡出动画,但它没有像我预期的那样工作。我怎样才能像WhatsApp一样实现动画?
right1.startAnimation(right1FadeOut);
right2.startAnimation(right2FadeOut);
right3.startAnimation(right3FadeOut);
这是结果。
尝试在 AnimationListener
s onAnimationStart
方法中以增加延迟开始后续动画。
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 )
{
}
} );
你的动画喜欢
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 );
重新开始时您可能需要稍微转动一下,但这样一来,它们应该是同步的。只需使用
开始第一个淡入动画
arrow1.startAnimation( arrow1FadeIn );
我会首先使用 Animator 对象而不是 Animation,然后我可以使用 AnimatorSet 将所有动画师作为一个组来控制。 (又名:订单)
例如:
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();
}
});
}
}
科特林:
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
}
}
我建议你使用Facebook Rebound library。
它像 facebook 一样支持 Spring
动画。它还具有称为 SpringChain
的很酷的功能,它使用 Spring 物理从头到尾自动播放一系列动画。您可以自定义如何为视图设置动画(缩放、alpha、平移...)
我正在尝试编写类似于 WhatsApp 呼叫屏幕中的动画。但我不知道实现这一目标的真正方法是什么。
为了实现这个动画,我开始尝试淡入淡出动画。这些是我设置的淡入淡出动画的方法。
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;
}
并且对于每个动画,animationlisteners onAnimationEnd 方法都会触发动画以重新启动。 fadeIn 动画启动 fadeOut 动画,fadeOut 启动 fadeIn 动画。
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");
}
});
初始化
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);
我开始为每个按钮调用淡出动画,但它没有像我预期的那样工作。我怎样才能像WhatsApp一样实现动画?
right1.startAnimation(right1FadeOut);
right2.startAnimation(right2FadeOut);
right3.startAnimation(right3FadeOut);
这是结果。
尝试在 AnimationListener
s onAnimationStart
方法中以增加延迟开始后续动画。
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 )
{
}
} );
你的动画喜欢
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 );
重新开始时您可能需要稍微转动一下,但这样一来,它们应该是同步的。只需使用
开始第一个淡入动画arrow1.startAnimation( arrow1FadeIn );
我会首先使用 Animator 对象而不是 Animation,然后我可以使用 AnimatorSet 将所有动画师作为一个组来控制。 (又名:订单)
例如:
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();
}
});
}
}
科特林:
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
}
}
我建议你使用Facebook Rebound library。
它像 facebook 一样支持 Spring
动画。它还具有称为 SpringChain
的很酷的功能,它使用 Spring 物理从头到尾自动播放一系列动画。您可以自定义如何为视图设置动画(缩放、alpha、平移...)