Jadual Kandungan
Tween动画
XML语法介绍
插值器 – Interpolator
自定义Interpolator
公共XML属性及对应的方法
ScaleAnimation – 缩放动画
RotateAnimation – 旋转动画
TranslateAnimation – 平移动画
AlphaAnimation – 渐变动画
AnimationSet – 动画集合
Frame动画
LayoutAnimationController
GridLayoutAnimationController
RecyclerView扩展
Rumah hujung hadapan web html tutorial Android动画三部曲之一 View Animation & LayoutAnimation_html/css_WEB-ITnose

Android动画三部曲之一 View Animation & LayoutAnimation_html/css_WEB-ITnose

Jun 24, 2016 am 11:27 AM

本篇文章对android的Tween动画帧动画以及布局动画进行总结。

  • Tween动画
  • XML语法介绍
  • 插值器 Interpolator
  • 自定义Interpolator
  • 公共XML属性及对应的方法
  • ScaleAnimation 缩放动画
  • xml定义缩放动画
  • 代码定义缩放动画
  • RotateAnimation 旋转动画
  • xml中设置旋转动画
  • 代码中设置旋转动画
  • TranslateAnimation 平移动画
  • xml中设置平移动画
  • 代码中设置平移动画
  • AlphaAnimation 渐变动画
  • xml中设置渐变动画
  • 代码中设置渐变动画
  • AnimationSet 动画集合
  • xml中设置set动画集合
  • Frame动画
  • xml设置帧动画
  • 代码中设置帧动画
  • LayoutAnimationController
  • xml定义LayoutAnimation
  • 代码中定义LayoutAnimation
  • GridLayoutAnimationController
  • xml中定义
  • 代码中设置
  • RecyclerView扩展
  • Tween动画

    Tween动画又称补间动画。通过对view的位置、大小、透明度、角度的改变来实现动画效果。

    补间动画的基类是Animation。我们通常使用它的直接子类RotateAnimationTranslateAnimationScaleAnimationAlphaAnimation

    补间动画可以通过xml进行定义(res/anim/xxx),然后通过AnimationUtils类进行加载;也可以通过完全代码进行设置。

    XML语法介绍

    <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] >    <alpha android:fromAlpha="float" android:toAlpha="float" />    <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" />    <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" />    <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" />    <set>        ...    </set></set>
    Salin selepas log masuk

    Animation类定义了很多常量和变量的初始值,比如:

    public static final int INFINITE = -1;public static final int RESTART = 1;public static final int REVERSE = 2;
    Salin selepas log masuk

    主要用到它的子类以及AnimationListener :

    public static interface AnimationListener {        /** * 动画开始的时候回调 * * @param animation The started animation. */        void onAnimationStart(Animation animation);        /** * 动画结束的时候回调。但是当设置动画重复次数为INFINITE的时候,该方法不会回调。 * * @param animation The animation which reached its end. */        void onAnimationEnd(Animation animation);        /** * 动画重复播放的时候回调 * * @param animation The animation which was repeated. */        void onAnimationRepeat(Animation animation);    }
    Salin selepas log masuk

    添加此监听器可以对动画做更多的操作。

    插值器 – Interpolator

    介绍动画之前,得先说说”插值器”。插值器的意思就是在播放动画的时候,改变播放的速率,可以使动画越来越快,或者越来越慢等。

    常用的是一下九个插值器:

    Baseinterpolator子类 Resource ID 描述
    AccelerateInterpolator @android:anim/accelerate_interpolator 加速变化(开始慢,越来越快)
    DecelerateInterpolator @android:anim/decelerate_interpolator 减速变化(开始快,越来越慢)
    AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 先加速后减速(中间速度最快)
    LinearInterpolator @android:anim/linear_interpolator 线性均匀变化
    OvershootInterpolator @android:anim/overshoot_interpolator 超出结尾的临界值,然后在缓慢回到结束值
    AnticipateInterpolator @android:anim/anticipate_interpolator 先向相反的方向改变一点,然后在加速播放
    AnticipateOvershootInterpolator @android:anim/anitcipate_overshoot_interpolator 先向相反的方向改变一点,然后在加速播放至超出结束值一点,然后在缓慢回到结束值
    BounceInterpolator @android:anim/bounce_interpolator 动画快结束的时候,模拟球落地的回弹效果
    CycleInterpolator @android:anim/cycle_interpolator 动画循环播放指定的次数

    自定义Interpolator

    一般来说,官方API给的这几个插值器就够实用了。不过还可以自定义Interpolator。可以简单的对系统的插值器进行一些参数值的修改:

    <?xml version="1.0" encoding="utf-8"?><InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
    Salin selepas log masuk

    这里推荐大家一个第三方的Interpolator库:

    https://github.com/cimi-chen/EaseInterpolator

    公共XML属性及对应的方法

    属性名称 对应的方法 描述
    android:duration setDuration(long) 动画持续的时间长度(单位是miliseconds)
    android:interpolator setInterpolator(Interpolator) 设置动画播放时的插值器
    android:repeatCount setRepeatCount(int) 设置动画播放重复次数
    android:repeatMode setRepeatMode(int) 设置动画重复的方式(当repeat count>0时才有效) “reverse“(2) or “restart“(1)
    android:startOffset setStartOffset(long) 设置动画开始播放的延迟时间
    android:fillAfter setFillAfter(boolean) 设置为true时,视图会停留在动画结束的状态。
    android:fillBefore setFillBefore(boolean) 默认值是true,视图会停留在动画开始的状态
    android:fillEnable setFillEnable(boolean) 默认值是false。如果是true,动画将会应用fillBefore值;否则,fillBefore的值会被忽略,transformation会在动画结束的时候被应用。
    android:detachWallpaper setDetachWallpaper(boolean) 默认值是false。如果为true,并且动画窗体有一个壁纸的话,那么动画只会应用给window,墙纸是静态不动的
    android:zAdjustment setZAdjustment(int) 允许在动画播放期间,调整播放内容在Z轴方向的顺序。”top“(1) or “normal“(0) or “bottom“(-1)

    android:zAdjustment:允许在动画播放期间,调整播放内容在Z轴方向的顺序:

  • normal(0):正在播放的动画内容保持当前的Z轴顺序,
  • top(1):在动画播放期间,强制把当前播放的内容放到其他内容的上面;
  • bottom(-1):在动画播放期间,强制把当前播放的内容放到其他内容之下
  • ScaleAnimation – 缩放动画

    XML属性名称 描述
    android:fromXScale 动画起始时,X轴坐标的伸缩尺寸。0.0表示收缩到没有。1.0表示正常没伸缩。>1.0表示放大。<1.0表示收缩。
    android:toXScale 动画结束时X轴坐标的伸缩尺寸
    android:fromYScale 动画起始时Y轴坐标的伸缩尺寸
    android:toYScale 动画结束时Y轴坐标的伸缩尺寸
    android:pivotX 缩放动画作用点在X轴方向上的位置。android:pivotX=”50”表示绝对定位,相对于零点偏移50 –> Animation.ABSOLUTE android:pivotX=”50%”表示相对控件本身 –> Animation.RELATE_TO_SELF android:pivotX=”50%p”表示相对控件的父控件 –> Animation.RELATE_TO_PARENT
    android:pivotY 缩放动画作用点在Y轴方向上的位置
    xml定义缩放动画
    <?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android" android:background="@color/blue_light" android:duration="1000" android:fillAfter="false" android:fillBefore="true" android:fromXScale="1" android:fromYScale="1" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:repeatCount="1" android:repeatMode="restart" android:startOffset="500" android:toXScale="0" android:toYScale="0" android:zAdjustment="bottom" />
    Salin selepas log masuk

    然后通过AnimationUtils类装载动画,进行应用。

    Animation scaleAnimation =  AnimationUtils.loadAnimation(this, R.anim.scale_anim);targetIv.startAnimation(scaleAnimation);
    Salin selepas log masuk
    代码定义缩放动画
    ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.5f, 1.0f, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);scaleAnimation.setDuration(1000);scaleAnimation.setInterpolator(new OvershootInterpolator());scaleAnimation.setFillAfter(true);targetIv.startAnimation(scaleAnimation);
    Salin selepas log masuk

    ScaleAnimation有4个构造方法。

    public ScaleAnimation(Context context, AttributeSet attrs) {}
    Salin selepas log masuk
    public ScaleAnimation(float fromX, float toX, float fromY, float toY) {}
    Salin selepas log masuk
    public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) {}
    Salin selepas log masuk
    public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
    Salin selepas log masuk

    第一个构造用于从资源文件中加载资源。我们主要用后三个。后面三个构造的区别就在设置变换中轴点与否。不指定pivotXType和pivotYType的话,默认采用ABSOLUTE形式,pivotX与pivotY的值都是相对于(0,0)左上角偏移的。

    pivotXType可设置的参数有三种:ABSOLUTE、RELATE_TO_SELF、RELATE_TO_PARENT。

  • ABSOLUTE表示当前设置的pivotX和pivotY值是绝对值,相对于左上角偏移。比如:android:pibotX=”50”
  • RELATE_TO_SELF表示设置的pivotX和pivotY是相对值。比如:android:pivotX = “50%”表示X方向中轴点在正中间。 取值范围是[0% ~ 100%]
  • RELATE_TO_PARENT也是表示相对值,是相对于该视图的父控件而言。比如:android:pivotX = “50%p”表示X方向中轴点是其父控件的中间位置。取值范围是[0% ~ 100%]
  • 效果如下:

    RotateAnimation – 旋转动画

    XML属性名称 描述
    android:fromDegrees 动画起始的角度(可正可负)
    android:toDegrees 动画终止的角度(可正可负)
    android:pivotX 旋转作用点在X轴方向上的位置。android:pivotX=”50”表示绝对定位,相对于零点偏移50 android:pivotX=”50%”表示相对控件本身 android:pivotX=”50%p”表示相对控件的父控件
    android:pivotY 旋转作用点在Y轴方向上的位置
    xml中设置旋转动画
    <?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2500" android:fillAfter="true" android:fromDegrees="-20" android:interpolator="@android:anim/overshoot_interpolator" android:pivotX="50%" android:pivotY="50%" android:toDegrees="320" />
    Salin selepas log masuk
    代码中设置旋转动画
    RotateAnimation rotateAnimation = new RotateAnimation(0.0f, 550.0f, Animation.RELATIVE_TO_SELF, 0.3f, Animation.RELATIVE_TO_SELF, 0.3f);rotateAnimation.setDuration(1500);rotateAnimation.setInterpolator(new OvershootInterpolator());rotateAnimation.setFillAfter(true);targetIv.startAnimation(rotateAnimation);
    Salin selepas log masuk

    效果图如下:

    TranslateAnimation – 平移动画

    XML属性名称 描述
    android:fromXDelta 平移动画起始位置X轴坐标
    android:toXDelta 平移动画结束位置X轴坐标
    android:fromYDelta 平移动画起始位置Y轴坐标
    android:toYDelta 平移动画结束位置Y轴坐标
    xml中设置平移动画:
    <?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:fromXDelta="0" android:fromYDelta="0" android:interpolator="@android:anim/anticipate_overshoot_interpolator" android:toXDelta="50%p" android:toYDelta="50%p" />
    Salin selepas log masuk
    代码中设置平移动画
    TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 0);translateAnimation.setDuration(1000);translateAnimation.setInterpolator(new AnticipateOvershootInterpolator());targetIv.startAnimation(translateAnimation);
    Salin selepas log masuk

    AlphaAnimation – 渐变动画

    XML属性名称 描述
    android:fromAlpha 动画开始时操作对象的alpha值
    android:toAlpha 动画终止时操作对象的alpha值
    xml中设置渐变动画:
    <?xml version="1.0" encoding="utf-8"?><alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:fromAlpha="1.0" android:interpolator="@android:anim/linear_interpolator" android:repeatCount="1" android:repeatMode="reverse" android:toAlpha="0.0" />
    Salin selepas log masuk
    代码中设置渐变动画:
    AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.2f);alphaAnimation.setDuration(1500);alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());alphaAnimation.setRepeatMode(Animation.REVERSE);alphaAnimation.setRepeatCount(1);targetIv.startAnimation(alphaAnimation);
    Salin selepas log masuk

    AnimationSet – 动画集合

    上面都是一个个的单独的动画,我们可以将很多个单独的动画组合到一起成为一个集合。

    动画集合也可以在xml中设置。需要用标签包括其他简单的动画。比上述公共动画属性多了一个android:shareInterpolator=”boolean”,表示是否对子动画设置相同的插值器。

    xml中设置set动画集合
    <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" android:shareInterpolator="false">    <alpha android:duration="1500" android:fillAfter="true" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.2" />    <scale android:duration="1000" android:fromXScale="0.8" android:fromYScale="0.8" android:interpolator="@android:anim/linear_interpolator" android:pivotX="60%" android:pivotY="20%" android:startOffset="1500" android:toXScale="0.3" android:toYScale="0.5" />    <translate android:duration="1000" android:fromXDelta="0" android:fromYDelta="0" android:interpolator="@android:anim/bounce_interpolator" android:startOffset="2500" android:toXDelta="200" android:toYDelta="200" />    <rotate android:duration="1000" android:fromDegrees="50" android:interpolator="@android:anim/anticipate_overshoot_interpolator" android:pivotX="50%p" android:pivotY="50%p" android:startOffset="3500" android:toDegrees="360" /></set>
    Salin selepas log masuk


    我们来看一个现象:
    设置了上面的set动画之后,开始运行的时候,会发现渐变动画开始运行的时候,会先变小,旋转一个角度,然后才开始动画。仔细分析xml代码之后,发现是在动画开始的时候,把scale和rotate中的初始状态给应用了。这时候想起了android:fillBefore属性。
    然后在scale、rotate 动画里添加了android:fillBefore=”false”属性之后,发现还是不好使。查看Animation类的源码发现,fillBefore必须在设置fillEnable=”true”的时候才神效。并且fillBefore的默认值是true,所以才会出现上述情况。

    再次修改之后,代码如下:

    <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" android:shareInterpolator="false">    <alpha android:duration="1500" android:fillAfter="true" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.2" />    <scale android:duration="1000" android:fillBefore="false" android:fillEnabled="true" android:fromXScale="0.8" android:fromYScale="0.8" android:interpolator="@android:anim/linear_interpolator" android:pivotX="60%" android:pivotY="20%" android:startOffset="1500" android:toXScale="0.3" android:toYScale="0.5" />    <translate android:duration="1000" android:fromXDelta="0" android:fromYDelta="0" android:interpolator="@android:anim/bounce_interpolator" android:startOffset="2500" android:toXDelta="200" android:toYDelta="200" />    <rotate android:duration="1000" android:fillBefore="false" android:fillEnabled="true" android:fromDegrees="50" android:interpolator="@android:anim/anticipate_overshoot_interpolator" android:pivotX="50%p" android:pivotY="50%p" android:startOffset="3500" android:toDegrees="360" /></set>
    Salin selepas log masuk

    效果如下:

    Frame动画

    Frame动画就是把图片一帧一帧的播放出来的显示效果,类似于gif图片。帧动画设置很简单,只需要把每一帧对应的图片按照顺序添加进去,然后设置每一帧的显示时长,然后为view控件设置该动画,播放就行了。

    xml设置帧动画:
    <?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">    <item android:drawable="@drawable/person1" android:duration="100" />    <item android:drawable="@drawable/person2" android:duration="100" />    <item android:drawable="@drawable/person3" android:duration="100" />    <ite android:drawable="@drawable/person4" android:duration="100" />    <item android:drawable="@drawable/person5" android:duration="100" />    <item android:drawable="@drawable/person6" android:duration="100" />    <item android:drawable="@drawable/person7" android:duration="100" /></animation-list>
    Salin selepas log masuk

    给ImageView设置动画:

    targetIv.setBackgroundResource(R.drawable.frame_anim);AnimationDrawable animationDrawable = (AnimationDrawable) targetIv.getBackground();animationDrawable.start();
    Salin selepas log masuk
    代码中设置帧动画
    AnimationDrawable animationDrawable = new AnimationDrawable();animationDrawable.setOneShot(false);animationDrawable.addFrame(getResources().getDrawable(R.drawable.person1), 200);animationDrawable.addFrame(getResources().getDrawable(R.drawable.person2), 200);animationDrawable.addFrame(getResources().getDrawable(R.drawable.person3), 200);animationDrawable.addFrame(getResources().getDrawable(R.drawable.person4), 200);animationDrawable.addFrame(getResources().getDrawable(R.drawable.person5), 200);targetIv.setImageDrawable(animationDrawable);animationDrawable.start();
    Salin selepas log masuk

    LayoutAnimationController

    Tween Animation和Frame Animation都是针对单个view操作的。而LayoutAnimationController可以针对一个ViewGroup进行动画操作,可以让一组view的每个view按照一定的规则展示动画。
    比如:可以针对listView、gridView或者recyclerView,定义item的出场动画,而不是非常死板的一下子全显示出来。

    一般对ListView使用layoutAnimation动画,对GridView使用gridLayoutAnimation动画。对RecyclerView来说,正常情况下只能使用layoutAnimation动画,应用gridLayoutAnimation动画的时候会报错。不错可以针对RecyclerView生成一个子类做一下处理进行支持gridLayoutAnimation动画。

    xml属性 对应的方法 描述
    android:delay setDelay(float) 动画播放的延迟时间
    android:animationOrder setOrder(int) 子view播放动画的顺序 [ normal
    android:interpolator setInterpolator(Interpolator) setIntepolator(Context, @InterpolatorRes int) 插值器
    android:animation LayoutAnimationController(animation) 指定子view的动画
    xml定义LayoutAnimation
    <?xml version="1.0" encoding="utf-8"?><layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:animation="@anim/item_list_anim" android:animationOrder="normal" android:delay="0.2" android:interpolator="@android:anim/bounce_interpolator" />
    Salin selepas log masuk
    <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:shareInterpolator="true">    <alpha android:fromAlpha="0.0" android:toAlpha="1.0" />    <translate android:fromXDelta="-100%" android:toXDelta="0%" /></set>
    Salin selepas log masuk
    代码中定义LayoutAnimation
    public LayoutAnimationController(Animation animation) {    this(animation, 0.5f);}
    Salin selepas log masuk
    public LayoutAnimationController(Animation animation, float delay) {    mDelay = delay;    setAnimation(animation);}
    Salin selepas log masuk

    LayoutAnimationController有三个构造函数,常用的时候上面两个。delay表示每个子view启动动画的延迟时间,默认是0.5f。delay以秒为单位

    Animation animation = AnimationUtils.loadAnimation(this, R.anim.item_list_anim);        LayoutAnimationController layoutAnimationController = new LayoutAnimationController(animation);        layoutAnimationController.setInterpolator(new AccelerateInterpolator());        layoutAnimationController.setDelay(0.5f);        layoutAnimationController.setOrder(LayoutAnimationController.ORDER_RANDOM);        recyclerView.setLayoutAnimation(layoutAnimationController);
    Salin selepas log masuk

    GridLayoutAnimationController

    GridLayoutAnimationController是LayoutAnimationController的子类。针对GridView做动画操作。

    xml属性 对应的方法 描述
    android:delay setDelay(float) 动画播放的延迟时间
    android:columnDelay setColumnDelay(float) 列播放动画的延迟时间
    android:rowDelay setRowDelay(float) 行播放动画的延迟时间
    android:animationOrder setOrder(int) 子view播放动画的顺序 [ normal
    android:animation LayoutAnimationController(animation) 指定子view的动画
    xml中定义
      <GridView android:id="@+id/test_grid_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnWidth="60dp" android:gravity="center" android:horizontalSpacing="10dp" android:layoutAnimation="@anim/grid_layout_anim" android:numColumns="3" android:padding="10dp" android:scrollbars="none" android:stretchMode="columnWidth" android:verticalSpacing="10dp" />
    Salin selepas log masuk
    <?xml version="1.0" encoding="utf-8"?><gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:animation="@anim/item_anim_alpha" android:columnDelay="0.5" android:direction="bottom_to_top|right_to_left" android:directionPriority="row" />
    Salin selepas log masuk
    <?xml version="1.0" encoding="utf-8"?><alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:fromAlpha="0.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="1.0" />
    Salin selepas log masuk
    代码中设置

    同样是使用一个Animation构造出GridLayoutAnimation对象,然后设置各种参数,最后设置此动画GridView即可。

    Animation animation = AnimationUtils.loadAnimation(this, R.anim.item_anim_alpha);GridLayoutAnimationController gridLayoutAnimationController = new GridLayoutAnimationController(animation);gridLayoutAnimationController.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP | GridLayoutAnimationController.DIRECTION_RIGHT_TO_LEFT);gridLayoutAnimationController.setDirectionPriority(GridLayoutAnimationController.PRIORITY_ROW);gridRecyclerView.setLayoutAnimation(gridLayoutAnimationController);
    Salin selepas log masuk

    效果如下:

    RecyclerView扩展

    正常情况下,我们可以对RecyclerView使用LayoutAnimation动画。但是如果对RecycleView使用动画的时候出现以下错误:

    AndroidRuntime: FATAL EXCEPTION: main                                                       Process: com.jacksen.demo.view, PID: 30770                                                  java.lang.ClassCastException: android.view.animation.LayoutAnimationController$AnimationParameters cannot be cast to android.view.animation.GridLayoutAnimationController$AnimationParameters                   at android.view.animation.GridLayoutAnimationController.getDelayForView(GridLayoutAnimationController.java:299)                   at android.view.animation.LayoutAnimationController.getAnimationForView(LayoutAnimationController.java:321)                   at android.view.ViewGroup.bindLayoutAnimation(ViewGroup.java:3717)                   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2892)                   ......
    Salin selepas log masuk

    意思就是GridLayoutAnimationController.AnimationParameters不能强转成LayoutAnimationController.AnimationParameters。

    RecyclerView的出现本来就是替代Listview的,但是它有可以展示出GridView的效果,但是怎么让RecyclerView设置GridLayoutManager的时候应用gridLayoutAnimation动画呢?

    我们先来看看Gridview怎么实现的?

    在GridView源码里面搜索”LayoutAnimation”关键字发现,只有一个attachLayoutAnimationParameters()的函数,里面将layoutAnimationParameters强转成GridLayoutAnimationController.AnimationParameters。

    @Override    protected void attachLayoutAnimationParameters(View child,            ViewGroup.LayoutParams params, int index, int count) {        GridLayoutAnimationController.AnimationParameters animationParams =                (GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;        if (animationParams == null) {            animationParams = new GridLayoutAnimationController.AnimationParameters();            params.layoutAnimationParameters = animationParams;        }        animationParams.count = count;        animationParams.index = index;        animationParams.columnsCount = mNumColumns;        animationParams.rowsCount = count / mNumColumns;        if (!mStackFromBottom) {            animationParams.column = index % mNumColumns;            animationParams.row = index / mNumColumns;        } else {            final int invertedIndex = count - 1 - index;            animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns);            animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns;        }    }
    Salin selepas log masuk

    然后就想到去RecyclerView中去找attachLayoutAnimationParameters()方法,但是没有,其父类ViewGroup里面有此方法:

    protected void attachLayoutAnimationParameters(View child,            LayoutParams params, int index, int count) {        LayoutAnimationController.AnimationParameters animationParams =                    params.layoutAnimationParameters;        if (animationParams == null) {            animationParams = new LayoutAnimationController.AnimationParameters();            params.layoutAnimationParameters = animationParams;        }        animationParams.count = count;        animationParams.index = index;    }
    Salin selepas log masuk

    由此可见RecyclerView默认实现了ViewGroup的LayoutAnimation。我们在RecyclerView中将此方法重写一下。不过要将mStackFromButtom参数的判断去掉

    public class GridRecyclerView extends RecyclerView {    public GridRecyclerView(Context context) {        super(context);    }    public GridRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public GridRecyclerView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    public void setAdapter(Adapter adapter) {        super.setAdapter(adapter);    }    @Override    public void setLayoutManager(LayoutManager layout) {        if (layout instanceof GridLayoutManager) {            super.setLayoutManager(layout);        } else {            throw new ClassCastException("you should only use the GridLayoutManager as LayoutManager when you use this " + this.getClass().getSimpleName() + " class");        }    }    @Override    protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params, int index, int count) {        if (getLayoutManager() != null && getLayoutManager() instanceof GridLayoutManager) {            GridLayoutAnimationController.AnimationParameters animationParams =                    (GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;            if (animationParams == null) {                animationParams = new GridLayoutAnimationController.AnimationParameters();                params.layoutAnimationParameters = animationParams;            }            int mNumColumns = ((GridLayoutManager) getLayoutManager()).getSpanCount();            animationParams.count = count;            animationParams.index = index;            animationParams.columnsCount = mNumColumns;            animationParams.rowsCount = count / mNumColumns;            final int invertedIndex = count - 1 - index;            animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns);            animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns;        } else {            super.attachLayoutAnimationParameters(child, params, index, count);        }    }}
    Salin selepas log masuk

    当我们使用GridLayoutManager的时候,不能使用此属性。

    /** * stackFromEnd is not supported by GridLayoutManager. Consider using * {@link #setReverseLayout(boolean)}. */    @Override    public void setStackFromEnd(boolean stackFromEnd) {        if (stackFromEnd) {            throw new UnsupportedOperationException(                    "GridLayoutManager does not support stack from end."                            + " Consider using reverse layout");        }        super.setStackFromEnd(false);    }
    Salin selepas log masuk

    此篇blog到此结束~
    感谢大家支持!如有错误,请指出~
    谢谢~

    参考:

    http://developer.android.com/intl/zh-cn/guide/topics/graphics/view-animation.html

    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0619/3090.html
    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3462.html?utm_source=tuicool&utm_medium=referral

    Kenyataan Laman Web ini
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

    Alat AI Hot

    Undresser.AI Undress

    Undresser.AI Undress

    Apl berkuasa AI untuk mencipta foto bogel yang realistik

    AI Clothes Remover

    AI Clothes Remover

    Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

    Undress AI Tool

    Undress AI Tool

    Gambar buka pakaian secara percuma

    Clothoff.io

    Clothoff.io

    Penyingkiran pakaian AI

    AI Hentai Generator

    AI Hentai Generator

    Menjana ai hentai secara percuma.

    Artikel Panas

    R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
    2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
    Repo: Cara menghidupkan semula rakan sepasukan
    1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
    Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
    4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

    Alat panas

    Notepad++7.3.1

    Notepad++7.3.1

    Editor kod yang mudah digunakan dan percuma

    SublimeText3 versi Cina

    SublimeText3 versi Cina

    Versi Cina, sangat mudah digunakan

    Hantar Studio 13.0.1

    Hantar Studio 13.0.1

    Persekitaran pembangunan bersepadu PHP yang berkuasa

    Dreamweaver CS6

    Dreamweaver CS6

    Alat pembangunan web visual

    SublimeText3 versi Mac

    SublimeText3 versi Mac

    Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

    Kesukaran mengemas kini caching laman web akaun rasmi: Bagaimana untuk mengelakkan cache lama yang mempengaruhi pengalaman pengguna selepas kemas kini versi? Kesukaran mengemas kini caching laman web akaun rasmi: Bagaimana untuk mengelakkan cache lama yang mempengaruhi pengalaman pengguna selepas kemas kini versi? Mar 04, 2025 pm 12:32 PM

    Cache kemas kini laman web akaun rasmi, perkara ini mudah dan mudah, dan ia cukup rumit untuk minum periuknya. Anda bekerja keras untuk mengemas kini artikel akaun rasmi, tetapi pengguna masih membuka versi lama. Dalam artikel ini, mari kita lihat kelainan dan bertukar di belakang ini dan bagaimana menyelesaikan masalah ini dengan anggun. Selepas membacanya, anda boleh dengan mudah menangani pelbagai masalah caching, yang membolehkan pengguna anda sentiasa mengalami kandungan segar. Mari kita bincangkan asas -asas terlebih dahulu. Untuk meletakkannya secara terang -terangan, untuk meningkatkan kelajuan akses, penyemak imbas atau pelayan menyimpan beberapa sumber statik (seperti gambar, CSS, JS) atau kandungan halaman. Kali seterusnya anda mengaksesnya, anda boleh mengambilnya secara langsung dari cache tanpa perlu memuat turunnya lagi, dan ia secara semula jadi cepat. Tetapi perkara ini juga pedang bermata dua. Versi baru dalam talian,

    Bagaimana cara menambah kesan strok kepada imej PNG di laman web? Bagaimana cara menambah kesan strok kepada imej PNG di laman web? Mar 04, 2025 pm 02:39 PM

    Artikel ini menunjukkan penambahan sempadan PNG yang cekap ke halaman web menggunakan CSS. Ia berpendapat bahawa CSS menawarkan prestasi unggul berbanding dengan JavaScript atau perpustakaan, memperincikan cara menyesuaikan lebar sempadan, gaya, dan warna untuk kesan halus atau menonjol

    Bagaimana saya menggunakan atribut pengesahan borang html5 untuk mengesahkan input pengguna? Bagaimana saya menggunakan atribut pengesahan borang html5 untuk mengesahkan input pengguna? Mar 17, 2025 pm 12:27 PM

    Artikel ini membincangkan menggunakan atribut pengesahan bentuk HTML5 seperti had, corak, min, max, dan panjang untuk mengesahkan input pengguna secara langsung dalam penyemak imbas.

    Apakah amalan terbaik untuk keserasian penyemak imbas dalam HTML5? Apakah amalan terbaik untuk keserasian penyemak imbas dalam HTML5? Mar 17, 2025 pm 12:20 PM

    Artikel membincangkan amalan terbaik untuk memastikan keserasian silang pelayar HTML5, memberi tumpuan kepada pengesanan ciri, peningkatan progresif, dan kaedah ujian.

    Apakah tujuan & lt; DATALIST & GT; unsur? Apakah tujuan & lt; DATALIST & GT; unsur? Mar 21, 2025 pm 12:33 PM

    Artikel ini membincangkan html & lt; datalist & gt; elemen, yang meningkatkan bentuk dengan menyediakan cadangan autokomplete, meningkatkan pengalaman pengguna dan mengurangkan kesilapan. Kira -kira: 159

    Apakah tujuan & lt; meter & gt; unsur? Apakah tujuan & lt; meter & gt; unsur? Mar 21, 2025 pm 12:35 PM

    Artikel ini membincangkan html & lt; meter & gt; elemen, digunakan untuk memaparkan nilai skalar atau pecahan dalam julat, dan aplikasi umum dalam pembangunan web. Ia membezakan & lt; meter & gt; dari & lt; kemajuan & gt; dan Ex

    Apakah tujuan & lt; kemajuan & gt; unsur? Apakah tujuan & lt; kemajuan & gt; unsur? Mar 21, 2025 pm 12:34 PM

    Artikel ini membincangkan html & lt; kemajuan & gt; elemen, tujuan, gaya, dan perbezaan dari & lt; meter & gt; elemen. Tumpuan utama adalah menggunakan & lt; kemajuan & gt; untuk menyelesaikan tugas dan & lt; meter & gt; untuk stati

    Bagaimana saya menggunakan html5 & lt; masa & gt; elemen untuk mewakili tarikh dan masa secara semantik? Bagaimana saya menggunakan html5 & lt; masa & gt; elemen untuk mewakili tarikh dan masa secara semantik? Mar 12, 2025 pm 04:05 PM

    Artikel ini menerangkan html5 & lt; time & gt; elemen untuk perwakilan tarikh/masa semantik. Ia menekankan pentingnya atribut DateTime untuk pembacaan mesin (format ISO 8601) bersama teks yang boleh dibaca manusia, meningkatkan aksesibilit

    See all articles