安卓中的双重 onAnimationEnd 如何使用?

6

我正在尝试创建一种幻灯片展示。为此,我需要在每个动画结束时更改图像并循环动画。但由于某种原因,同一事件会在每个动画中重复发生。

public cPhotoSlide(Activity _activity, DBHelper _helper, int idMenu, cItemViewer _ItemViewer){
    activity        = _activity;
    helper          = _helper;
    ImageManager    = helper.ImageManager;
    ItemViewer      = _ItemViewer;
    cursor          = 0;        
    itemIds         = ChildsItemsToTable(idMenu);
    MainLayout      = (RelativeLayout) activity.findViewById(R.id.fon);
    SliderObj       = activity.getLayoutInflater().inflate(R.layout.photo_slide, MainLayout, true);
    SlideImage      = (ImageView) SliderObj.findViewById(R.id.slide_image);
    SlideImage.setImageBitmap(ImageManager.loadImage(activity.getApplicationContext(),itemIds.get(cursor)));

    animationSlide  = (AnimationSet) AnimationUtils.loadAnimation(activity.getApplicationContext(), R.anim.slide);

    animationSlide.getAnimations().get(1).setAnimationListener(
            new AnimationListener() {
                public void onAnimationStart(Animation animation) {}
                public void onAnimationRepeat(Animation animation) {}
                public void onAnimationEnd(Animation animation) {
                    Log.d(LOG_TAG,"Cursor = "+cursor+"/"+itemIds.size());
                    if (cursor >= itemIds.size()-1) {
                        cursor = 0;
                    } else {
                        cursor += 1;
                    }
                    if (itemIds.get(cursor).content != 0) {
                        SlideImage.setImageBitmap(ImageManager.loadImage(itemIds.get(cursor)));
                    }
                    SlideImage.startAnimation(animationSlide);
                }
            }
    );

    SlideImage.startAnimation(animationSlide);
}

在XML中:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">
    <alpha
        android:duration="250"
        android:fromAlpha="0.0"
        android:toAlpha="1.0">
    </alpha>
    <alpha
        android:startOffset="2000"
        android:duration="250"
        android:fromAlpha="1.0"
        android:toAlpha="0.0">
    </alpha>
</set>

在日志中:

01-30 15:52:26.700: D/cPhotoSlide(22301): Cursor = 0/207
01-30 15:52:26.716: D/cPhotoSlide(22301): Cursor = 1/207
01-30 15:52:28.990: D/cPhotoSlide(22301): Cursor = 2/207
01-30 15:52:29.005: D/cPhotoSlide(22301): Cursor = 3/207
01-30 15:52:31.279: D/cPhotoSlide(22301): Cursor = 4/207
01-30 15:52:31.302: D/cPhotoSlide(22301): Cursor = 5/207
01-30 15:52:33.575: D/cPhotoSlide(22301): Cursor = 6/207
01-30 15:52:33.591: D/cPhotoSlide(22301): Cursor = 7/207
01-30 15:52:35.865: D/cPhotoSlide(22301): Cursor = 8/207
01-30 15:52:35.888: D/cPhotoSlide(22301): Cursor = 9/207
01-30 15:52:38.161: D/cPhotoSlide(22301): Cursor = 10/207
01-30 15:52:38.177: D/cPhotoSlide(22301): Cursor = 11/207

我在你的代码片段中没有看到你的问题。你是如何得出onAnimationEnd()被触发两次的结论的? - class stacker
@class-stacker 我在日志的时间表中定义了它。 - ftp27
2个回答

6

你的动画集由两个动画组成,你的代码被每个动画调用,在以下情况下可以解决此问题:

animationSlide.getAnimations().get(1).setAnimationListener(.....);

代替
animationSlide.setAnimationListener(.....);

1
也许我在加载这个动画时错了,因为现在动画立即关闭,忽略了 android:startOffset="2000"animationSlide = (AnimationSet) AnimationUtils.loadAnimation(activity.getApplicationContext(), R.anim.slide); - ftp27
发布了该类的所有构造函数。 - ftp27
请不要在布局XML中设置ImageBitmap并设置imageview大小,使用以下代码代替: android:layout_width="50dp" android:layout_height="50dp" - Mr.Me
添加 android:startOffset = "100" 到第一个动画后,问题奇妙地解决了。 - ftp27

2

我的解决方案是从.setAnimationListener更改为.withEndAction

示例:

 my_button.animate()
     .setDuration(10)
     .scaleX(1)
     .scaleY(1)
     .withEndAction(() -> (your action goes here) ).start();

解释:

.withEndAction()是一个可运行的方法,一旦启动就会被删除。因此,Runnable只会执行一次,而Listener可能会被调用多次。


这个代码可以运行,但是需要注意的是,“只有在动画正常结束时才会执行该操作;如果在动画期间取消了ViewPropertyAnimator,则不会运行可运行项。” 因此,如果例如视图应该在动画后启用,则这不是一个好的位置,因为无法保证执行。 - Manuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接