转载请注明出处:http://blog.csdn.net/crazy1235/article/details/50612827
本篇文章对android的Tween动画和帧动画以及布局动画进行总结。
Tween动画又称补间动画。通过对view的位置、大小、透明度、角度的改变来实现动画效果。
补间动画的基类是Animation。我们通常使用它的直接子类RotateAnimation、TranslateAnimation、ScaleAnimation、AlphaAnimation。
补间动画可以通过xml进行定义(res/anim/xxx),然后通过AnimationUtils类进行加载;也可以通过完全代码进行设置。
<?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>
Animation类定义了很多常量和变量的初始值,比如:
public static final int INFINITE = -1;
public static final int RESTART = 1;
public static final int REVERSE = 2;
主要用到它的子类以及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);
}
添加此监听器可以对动画做更多的操作。
介绍动画之前,得先说说”插值器”。插值器的意思就是在播放动画的时候,改变播放的速率,可以使动画越来越快,或者越来越慢等。
常用的是一下九个插值器:
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 | 动画循环播放指定的次数 |
一般来说,官方API给的这几个插值器就够实用了。不过还可以自定义Interpolator。可以简单的对系统的插值器进行一些参数值的修改:
<?xml version="1.0" encoding="utf-8"?>
<InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
这里推荐大家一个第三方的Interpolator库:
https://github.com/cimi-chen/EaseInterpolator
属性名称 | 对应的方法 | 描述 |
---|---|---|
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轴方向的顺序:
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 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" />
然后通过AnimationUtils类装载动画,进行应用。
Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
targetIv.startAnimation(scaleAnimation);
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);
ScaleAnimation有4个构造方法。
public ScaleAnimation(Context context, AttributeSet attrs) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
第一个构造用于从资源文件中加载资源。我们主要用后三个。后面三个构造的区别就在设置变换中轴点与否。不指定pivotXType和pivotYType的话,默认采用ABSOLUTE形式,pivotX与pivotY的值都是相对于(0,0)左上角偏移的。
pivotXType可设置的参数有三种:ABSOLUTE、RELATE_TO_SELF、RELATE_TO_PARENT。
效果如下:
XML属性名称 | 描述 |
---|---|
android:fromDegrees | 动画起始的角度(可正可负) |
android:toDegrees | 动画终止的角度(可正可负) |
android:pivotX | 旋转作用点在X轴方向上的位置。android:pivotX=”50”表示绝对定位,相对于零点偏移50 android:pivotX=”50%”表示相对控件本身 android:pivotX=”50%p”表示相对控件的父控件 |
android:pivotY | 旋转作用点在Y轴方向上的位置 |
<?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" />
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);
效果图如下:
XML属性名称 | 描述 |
---|---|
android:fromXDelta | 平移动画起始位置X轴坐标 |
android:toXDelta | 平移动画结束位置X轴坐标 |
android:fromYDelta | 平移动画起始位置Y轴坐标 |
android:toYDelta | 平移动画结束位置Y轴坐标 |
<?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" />
TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 0);
translateAnimation.setDuration(1000);
translateAnimation.setInterpolator(new AnticipateOvershootInterpolator());
targetIv.startAnimation(translateAnimation);
XML属性名称 | 描述 |
---|---|
android:fromAlpha | 动画开始时操作对象的alpha值 |
android:toAlpha | 动画终止时操作对象的alpha值 |
<?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" />
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);
上面都是一个个的单独的动画,我们可以将很多个单独的动画组合到一起成为一个集合。
动画集合也可以在xml中设置。需要用标签包括其他简单的动画。比上述公共动画属性多了一个android:shareInterpolator=”boolean”,表示是否对子动画设置相同的插值器。
<?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>
我们来看一个现象:
设置了上面的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>
效果如下:
Frame动画就是把图片一帧一帧的播放出来的显示效果,类似于gif图片。帧动画设置很简单,只需要把每一帧对应的图片按照顺序添加进去,然后设置每一帧的显示时长,然后为view控件设置该动画,播放就行了。
<?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>
给ImageView设置动画:
targetIv.setBackgroundResource(R.drawable.frame_anim);
AnimationDrawable animationDrawable = (AnimationDrawable) targetIv.getBackground();
animationDrawable.start();
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();
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 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" />
<?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>
public LayoutAnimationController(Animation animation) {
this(animation, 0.5f);
}
public LayoutAnimationController(Animation animation, float delay) {
mDelay = delay;
setAnimation(animation);
}
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);
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的动画 |
<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" />
<?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" />
<?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" />
同样是使用一个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);
效果如下:
正常情况下,我们可以对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)
......
意思就是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;
}
}
然后就想到去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;
}
由此可见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);
}
}
}
当我们使用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);
}
此篇blog到此结束~
感谢大家支持!如有错误,请指出~
谢谢~
参考:
http://developer.android.com/intl/zh-cn/guide/topics/graphics/view-animation.html
http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.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