Android CircularReveal 错误:在同一视图上启动另一种类型的动画师后不工作
Android CircularReveal bug: Not working after starting another type of animator on the same view
我有一个带有 RecyclerView 的应用程序,在每个项目中我都使用 onTouch() 实现了滑动到 star/dismiss 行为。我的实现没有问题,我可以处理左右滑动并从 RecyclerView 声明拖动。
每一项都是RevealFrameLayout,上面是content,下面是原始布局和要显示的布局,就像这样:
顶部布局:
下方布局(顶部显示层):
布局下方(显示前的默认布局):
在那里我显示了顶部显示层(彩色层)并且一切正常,直到我添加了另一个 ObjectAnimator 来隐藏星形布局(制作 starred/unstarred),当显示第一次工作时,然后另一次滑动将执行隐藏动画,然后第三次,它应该再次显示,它真正启动动画(通过调试 start() 被执行)但它没有显示。隐藏动画师第 4 次工作但没有显示布局。
触发任意动作的方法:
void triggerAction(SwipeAction swipeAction, final Note note, final int position) {
if (swipeAction.getActionId() == SwipeAction.STAR) {
if (note.isStarred() && !hidden && !hideAnimating && !justAnimated) {
starActionLayout.setVisibility(View.VISIBLE);
archiveActionLayout.setVisibility(View.GONE);
Animator hideAnim = AnimationUtils.createHideAnimation(revealStar);
hideAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
revealStar.setVisibility(View.INVISIBLE);
hideAnimating = false;
hidden = true;
note.setStarred(false);
MainActivity.notesController.set(position, note);
super.onAnimationEnd(animation);
}
});
hideAnim.start();
revealStar.setVisibility(View.VISIBLE); // DEBUG: Only to make sure the star layout is shown.
justAnimated = true;
hideAnimating = true;
revealAnimating = false;
revealed = false;
hidden = false;
} else if (!note.isStarred() && !revealAnimating && !revealed && !justAnimated) {
starActionLayout.setVisibility(View.VISIBLE);
archiveActionLayout.setVisibility(View.GONE);
final ObjectAnimator revealAnim = (ObjectAnimator) AnimationUtils.createCircularReveal(revealStar, (int) getCenterX(starActionImage), (int) getCenterY(starActionImage), 0, (float) getRadius(starActionLayout));
revealAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
revealAnimating = false;
revealed = true;
note.setStarred(true);
MainActivity.notesController.set(position, note);
super.onAnimationEnd(animation);
}
});
revealAnim.start();
justAnimated = true;
revealAnimating = true;
hideAnimating = false;
hidden = false;
revealed = false;
revealStar.setVisibility(View.VISIBLE);
}
} else if (swipeAction.getActionId() == SwipeAction.ARCHIVE) {
if (!revealAnimating && !revealed) {
int added = starActionLayout.getWidth();
starActionLayout.setVisibility(View.GONE);
archiveActionLayout.setVisibility(View.VISIBLE);
Animator revealAnim = AnimationUtils.createCircularReveal(revealArchive, (int) getCenterX(archiveActionImage) + added, (int) getCenterY(archiveActionImage), 0, (float) getRadius(archiveActionLayout));
revealAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
revealAnimating = false;
revealed = true;
super.onAnimationEnd(animation);
}
});
revealAnim.start();
revealAnimating = true;
revealArchive.setVisibility(View.VISIBLE);
}
}
}
我的条件没有问题,因为调试显示 reveal animator show 代码在应该执行的时候执行。 AnimationUtils
是一个自定义的 class,它包装了 ViewAnimationUtils.createCircularReveal(params)
和另一个自定义的 ObjectAnimator createHideAnimator()
,这也没有问题。
AnimationUtils.java
:
package com.skaldebane.util.graphics;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.os.Build;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.LinearInterpolator;
public class AnimationUtils {
public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
else return io.codetail.animation.ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
}
public static Animator createHideAnimation(View view) {
ObjectAnimator hideAnim = new ObjectAnimator();
hideAnim.setPropertyName("alpha");
hideAnim.setFloatValues(1.0F, 0.0F);
hideAnim.setDuration(300);
hideAnim.setInterpolator(new LinearInterpolator());
hideAnim.setTarget(view);
return hideAnim;
}
}
注意:不要让我改用 ItemTouchHelper,因为这不是我的问题的主题,也不能解决问题。
我刚刚弄清楚了问题所在。这很简单,但很难注意到。当我应用隐藏动画器时,它会将 alpha 永久设置为 0,这意味着该视图将永远不会再次出现。我只需要在调用 view.setVisiblity(View.INVISIBLE);
.
后直接使用 view.setAlpha(1.0F);
我有一个带有 RecyclerView 的应用程序,在每个项目中我都使用 onTouch() 实现了滑动到 star/dismiss 行为。我的实现没有问题,我可以处理左右滑动并从 RecyclerView 声明拖动。
每一项都是RevealFrameLayout,上面是content,下面是原始布局和要显示的布局,就像这样:
顶部布局:
下方布局(顶部显示层):
布局下方(显示前的默认布局):
在那里我显示了顶部显示层(彩色层)并且一切正常,直到我添加了另一个 ObjectAnimator 来隐藏星形布局(制作 starred/unstarred),当显示第一次工作时,然后另一次滑动将执行隐藏动画,然后第三次,它应该再次显示,它真正启动动画(通过调试 start() 被执行)但它没有显示。隐藏动画师第 4 次工作但没有显示布局。
触发任意动作的方法:
void triggerAction(SwipeAction swipeAction, final Note note, final int position) {
if (swipeAction.getActionId() == SwipeAction.STAR) {
if (note.isStarred() && !hidden && !hideAnimating && !justAnimated) {
starActionLayout.setVisibility(View.VISIBLE);
archiveActionLayout.setVisibility(View.GONE);
Animator hideAnim = AnimationUtils.createHideAnimation(revealStar);
hideAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
revealStar.setVisibility(View.INVISIBLE);
hideAnimating = false;
hidden = true;
note.setStarred(false);
MainActivity.notesController.set(position, note);
super.onAnimationEnd(animation);
}
});
hideAnim.start();
revealStar.setVisibility(View.VISIBLE); // DEBUG: Only to make sure the star layout is shown.
justAnimated = true;
hideAnimating = true;
revealAnimating = false;
revealed = false;
hidden = false;
} else if (!note.isStarred() && !revealAnimating && !revealed && !justAnimated) {
starActionLayout.setVisibility(View.VISIBLE);
archiveActionLayout.setVisibility(View.GONE);
final ObjectAnimator revealAnim = (ObjectAnimator) AnimationUtils.createCircularReveal(revealStar, (int) getCenterX(starActionImage), (int) getCenterY(starActionImage), 0, (float) getRadius(starActionLayout));
revealAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
revealAnimating = false;
revealed = true;
note.setStarred(true);
MainActivity.notesController.set(position, note);
super.onAnimationEnd(animation);
}
});
revealAnim.start();
justAnimated = true;
revealAnimating = true;
hideAnimating = false;
hidden = false;
revealed = false;
revealStar.setVisibility(View.VISIBLE);
}
} else if (swipeAction.getActionId() == SwipeAction.ARCHIVE) {
if (!revealAnimating && !revealed) {
int added = starActionLayout.getWidth();
starActionLayout.setVisibility(View.GONE);
archiveActionLayout.setVisibility(View.VISIBLE);
Animator revealAnim = AnimationUtils.createCircularReveal(revealArchive, (int) getCenterX(archiveActionImage) + added, (int) getCenterY(archiveActionImage), 0, (float) getRadius(archiveActionLayout));
revealAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
revealAnimating = false;
revealed = true;
super.onAnimationEnd(animation);
}
});
revealAnim.start();
revealAnimating = true;
revealArchive.setVisibility(View.VISIBLE);
}
}
}
我的条件没有问题,因为调试显示 reveal animator show 代码在应该执行的时候执行。 AnimationUtils
是一个自定义的 class,它包装了 ViewAnimationUtils.createCircularReveal(params)
和另一个自定义的 ObjectAnimator createHideAnimator()
,这也没有问题。
AnimationUtils.java
:
package com.skaldebane.util.graphics;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.os.Build;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.LinearInterpolator;
public class AnimationUtils {
public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
else return io.codetail.animation.ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
}
public static Animator createHideAnimation(View view) {
ObjectAnimator hideAnim = new ObjectAnimator();
hideAnim.setPropertyName("alpha");
hideAnim.setFloatValues(1.0F, 0.0F);
hideAnim.setDuration(300);
hideAnim.setInterpolator(new LinearInterpolator());
hideAnim.setTarget(view);
return hideAnim;
}
}
注意:不要让我改用 ItemTouchHelper,因为这不是我的问题的主题,也不能解决问题。
我刚刚弄清楚了问题所在。这很简单,但很难注意到。当我应用隐藏动画器时,它会将 alpha 永久设置为 0,这意味着该视图将永远不会再次出现。我只需要在调用 view.setVisiblity(View.INVISIBLE);
.
view.setAlpha(1.0F);