美文网首页
[Gankly] View animate cancel 无效

[Gankly] View animate cancel 无效

作者: leftcoding | 来源:发表于2017-04-01 17:13 被阅读746次

    Gankly

    基于干货Api、妹子图做的一个应用。应用包含干货 androi 、ios 、妹子,其他还有几个模块,包括新鲜事(煎蛋)、科技资讯、团队博客,以及抓包获取百思不得姐接口,做了视频跟给图片这2个模块。有兴趣的朋友,可以访问这个开源项目,如果有什么问题,可以留言,也可以联系我。

    项目地址: https://github.com/leftcoding/GankLy

    写这个文章的目的,因为在做这个项目中,总会碰到一些问题。所以,我觉得有必要把自己碰到的问题,解决问题的方法,写在以后的文章中,让其他碰到同样问题的人,少走一些冤枉路。

    项目中要实现一个效果,就是一个提示框,从右向左滑动,之后再从左往右消失。类似图下:

    1.gif

    看到图的第一个反映就是用动画来实现。因为项目是支持5.0+。所以,直接用新的代码段来实现。
    布局

    </RelativeLayout>
        <RelativeLayout
            android:id="@+id/browse_rl_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/item_author_bg">
    
            <TextView
                android:id="@+id/progress_txt_page"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
            <ImageView
                android:id="@+id/brose_img_auto"
                style="@style/Widget.AppCompat.ActionButton.Overflow"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </RelativeLayout>
    
        <TextView
            android:id="@+id/browse_txt_auto_tip"
            android:layout_width="180dp"
            android:layout_height="40dp"
            android:layout_above="@id/browse_rl_navigation"
            android:layout_marginEnd="-180dp"
            android:layout_toEndOf="@id/browse_rl_navigation"
            android:background="@drawable/item_author_bg"
            android:gravity="center"
            android:padding="8dp"
            android:text="@string/gralley_auto_tip"
            android:textColor="?attr/colorAccent"
            android:textSize="@dimen/normalSize" />
    </RelativeLayout>
    

    GalleryActivity

    txtAutoTip.animate().translationX(-getTipWidth).setDuration(300).setListener(newAnimator.AnimatorListener() {
    
    @Override
    public voidonAnimationStart(Animatoranimation) {
    txtAutoTip.setAlpha(1);
    }
    
    @Override
    public voidonAnimationEnd(Animatoranimation) {
    // 之后从左往右动画
    txtAutoTip.animate().alpha(0).translationX(0).setDuration(3000).setListener().start();
    }
    
    @Override
    public voidonAnimationCancel(Animatoranimation) {
    }
    @Override
    public voidonAnimationRepeat(Animatoranimation) {
    }
    }).start();
    
    

    这样就写好代码了,实现起来也达到了效果,但是,如果用户这个时候点击返回键或者关闭activity,那么,就会出现空指针

    这个是我在activity ondestory方法

    @Override
        protected void onDestroy() {
             // 当activity 结束时,退出动画
            txtAutoTip.animate().cancel();
            super.onDestroy();
        }
    

    但是为什么View 是空指针呢?
    只有一个问题,就是当activity 结束时,View 的取消动画根本没有执行到,所以导致空指针。那么就来看下为什么取消没有效果。

    我们先从View animate方法开始看。找到源码


    这就是 new 一个 ViewPropertyAnimator 对象,然后我们找到 ViewPropertyAnimator 的 cancel 方法。

    看到这里,Animator runningAnim.cancel(); 就知道了,有关于动画的取消都在这里。
    然后看代码知道,这是foreach循环,那么来源就是mAnimatorMap。
    找到mAnimatorMap 数组添加的代码。

    添加元素在 startAnimation 方法中。那么startAnimation方法,在哪里调用呢?

    ![]$4$%35BPN`H.png](https://img.haomeiwen.com/i1450309/847e2c3cc1f10294.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    原来在 start 的时候,就开始调用了 startAnimation ,也就是在view.animate().start();的时候就把这个动画元素添加到数组里,这样就比较清楚了。

    往回继续看看 startAnimation 方法,添加的是ValueAnimator 对象。那么,我就去ValueAnimator 对象中。找到 cancel 方法。

    这里 mListeners 数组循环调用 AnimatorListener 的 onAnimationCancel 方法。那我们查找 mListeners 数组的来源,发现在 ValueAnimator 类中,并没有mListeners 数组,那么就有可能,数组来于是父类中。那么去父类看看。

    =

    父类是 Animator。

    进去 Animator 发现果然有 mListeners 数组,看看数组初添加。

    发现数组添加是在 addListener 方法中。那么哪里调用 addListener 方法呢?这个时候,就回到最开始添加这个ValueAnimator 对象的地方,那么就是在一开始就提到的ViewPropertyAnimator对象的startAnimation方法中。ValueAnimator,调用addListener方法添加AnimatorListener接口。那么也就是mAnimatorEventListener这个类。

    那我们来看看mAnimatorEventListener类。


    在ViewPropertyAnimator类,一开始就初始化好了。看下这个类的onAnimationCancel方法。


    可以发现当 mListener != null的时候才执行。那么mListener 设置时候

    也就是View.animate().setListener() 的时候
    所以最后也就说,没有setListener,那么View animate cancel 设置是没有效果的。

    最后想说。有兴趣的可以看看我的项目 。

    项目地址: https://github.com/leftcoding/GankLy

    相关文章

      网友评论

          本文标题:[Gankly] View animate cancel 无效

          本文链接:https://www.haomeiwen.com/subject/xflhbttx.html