注意事项:
1. 修改默认布局变更动画的前提是先启用布局变更动画(请参考:使用视图默认布局动画);
2. 布局更改动画是分类型设置,没有设置的将以系统默认动画;
3. 布局变更的动画播放时长不能超过系统默认值,超过默认值将以默认值为动画时长;
4. 对于 CHANGE_APPEARING
动画和 CHANGE_DISAPPEARING
动画,请参考:LayoutTransition 详解。
LayoutTransition
类是用来为 ViewGroup
对象内的布局发生变更自动添加动画的。前面介绍的两种为 ViewGroup
启用布局变化动画都是同样的原理(XML 布局中配置和代码中配置),就是为 ViewGroup
设置一个 LayoutTransition
对象,设置之后会使用系统默认的动画,开发者也可以指定自定义的动画。
ViewGroup
布局变更可以概括为两类变更(出现和消失),这些变更伴随着四种变更动画(APPEARING
、 CHANGE_APPEARING
、DISAPPEARING
和 CHANGE_DISAPPEARING
)。在默认情况下,DISAPPEARING
动画和 CHANGE_APPEARING
都会立即开始,另一类动画将会根据动画的默认时间延迟开始。这样一来,就形成了这样一条动画序列:当一个项目添加到布局中时,容器的其他子项目就会先移动(为了腾出空间给新项目),然后新增的项目就会伴随着 APPEARING
动画添加进来。相反地,当一个项目从容器中移除时,该项目会先伴随 DISAPPEARING
动画从容器中移除,然后其他项目就会伴随动画移动(为了填充移除项目产生的间隙) 。如果你不想使用这种默认的编排顺序,可以调用 setDuration(int, long)
和 setStartDelay(int, long)
方法适当地调整某些(或者全部)动画。
特别注意:任何情况下,如果在 DISAPPEARING
动画完成之前就开始 APPEARING
动画, DISAPPEARING
动画就会立即停止,并且恢复 DISAPPEARING
动画产生的所有效果。相反地,如果在 APPEARING
动画完成之前就开始 DISAPPEARING
动画, APPEARING
动画也会立即停止,并且恢复 APPEARING
动画产生的效果。(此处说的是对于一个项目的状态,即中断了当前动画反操作的情况)
过渡指定的所有动画,包括默认的和用户自定义的,都只是模板。也就是说,这些动画的存在是为了保留基本的动画属性,例如时长、开始延时和添加动画的属性。但是,实际的目标对象以及这些属性的始值和结束值,都会在每次运行过渡时自动设置。每一个动画都是从原始副本中克隆,然后向克隆中填充需要动画对象的动态值(例如:由布局事件而移动的布局容器中的子项)以及变化的值(例如:对象的位置、大小)。推送给动画的实际值取决于动画指定的属性。例如:默认的 CHANGE_APPEARING
动画指定动画属性有 left
、top
、right
、bottom
、scrollX
和 scrollY
。在过度开始时,这些属性的值就会使用布局前和布局后的值进行更新。假如使用已知目标对象和属性名称的 ObjectAnimator
对象自定义动画,这些动画也会以同样的方式填充目标和动画值。
LayoutTransition
类以及相关的 XML 标记 animateLayoutChanges ="true"
,为直接情况下的自动变更提供了一个简单实用的工具。由于布局多个层级之间的相互关系,因此无法在多层次嵌套视图上使用 LayoutTransition
。另外,在添加或者移除项目时同时滚动的容器,也可能不适用这个工具,因为在动画运行时容器也正在滚动,当动画结束之后,由 LayoutTransition
计算出来的动画前后的位置可能跟实际位置不匹配。你可以在这种特殊情况下通过设置 CHANGE_APPEARING
和 CHANGE_DISAPPEARING
动画对象为 null
的方法禁用这类变更动画,并且适当的设置其他动画的 startDelay
。
更多关于 LayoutTransition
相关接口介绍请参考Google 官方文档: LayoutTransition
在 使用 LayoutTransition 类为 ViewGroup 添加布局动画 章节简单介绍了使用 LayoutTransition
自定义布局变更动画,笔者在尝试过程中发现, APPEARING
和 DISAPPEARING
l两个动画跟 CHANGE_APPEARING
和 CHANGE_DISAPPEARING
这两个动画不一样。前者适用类似缩放、渐变这类属性动画即可,但是后者却不行,必须包含 left
、top
、right
、bottom
、scrollX
和 scrollY
这些属性,大家在自定义布局变更动画的时候,一定要注意这点,否则设置了无效的动画,会无动画效果。笔者查看了下 LayoutTransition
源码,其定义默认动画的代码是这样的,大家在自定义自己的布局变更动画时可以参考下:
public LayoutTransition() {
if (defaultChangeIn == null) {
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);
PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1);
PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1);
PropertyValuesHolder pvhScrollX = PropertyValuesHolder.ofInt("scrollX", 0, 1);
PropertyValuesHolder pvhScrollY = PropertyValuesHolder.ofInt("scrollY", 0, 1);
defaultChangeIn = ObjectAnimator.ofPropertyValuesHolder((Object)null,
pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScrollX, pvhScrollY);
defaultChangeIn.setDuration(DEFAULT_DURATION);
defaultChangeIn.setStartDelay(mChangingAppearingDelay);
defaultChangeIn.setInterpolator(mChangingAppearingInterpolator);
defaultChangeOut = defaultChangeIn.clone();
defaultChangeOut.setStartDelay(mChangingDisappearingDelay);
defaultChangeOut.setInterpolator(mChangingDisappearingInterpolator);
defaultChange = defaultChangeIn.clone();
defaultChange.setStartDelay(mChangingDelay);
defaultChange.setInterpolator(mChangingInterpolator);
defaultFadeIn = ObjectAnimator.ofFloat(null, "alpha", 0f, 1f);
defaultFadeIn.setDuration(DEFAULT_DURATION);
defaultFadeIn.setStartDelay(mAppearingDelay);
defaultFadeIn.setInterpolator(mAppearingInterpolator);
defaultFadeOut = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
defaultFadeOut.setDuration(DEFAULT_DURATION);
defaultFadeOut.setStartDelay(mDisappearingDelay);
defaultFadeOut.setInterpolator(mDisappearingInterpolator);
mChangingAppearingAnim = defaultChangeIn;
mChangingDisappearingAnim = defaultChangeOut;
mChangingAnim = defaultChange;
mAppearingAnim = defaultFadeIn;
mDisappearingAnim = defaultFadeOut;
所有的效果都是以性能为代价的,用于更新界面的 Animator
会使动画运行的每一帧都进行额外的渲染。因此,使用资源密集型动画可能会对应用的性能产生负面影响,所以开发者要合理使用动画。
上一篇:Android 属性动画(四)使用动画插值器
下一篇:Android 属性动画(六)使用 ViewPropertyAnimator 实现多属性动画效果
属性动画系统不但能轻松为视图对象本身添加动画效果,而且提供了对 ViewGroup 布局的更改添加动画效果的功能。 可使用 LayoutTransition 类为ViewGroup 内的布局更改添加动画效果。当向 ViewGroup 中添加或删除视图时,或者使用 setVisibility() 方法改变视图的可见性(VISIBLE、INVISIBLE 或 GONE)时,这些视图会经历出现和消失动画,或者以动画的形
一、布局动画
布局动画的作用于ViewGroup,执行动画效果的是内部的子View。布局动画在android中可以通过LayoutAnimation或LayoutTransition来实现。
1.LayoutAnimation
LayoutAnimation实际上是一...
public class MyCustomView extends ViewGroup implements View.OnClickListener {
private OnMenuItemClickListener mMenuItemClickListener;
* 点击子菜单项的回调接口
public interface OnMenuItemClickListener {
void onClick(View view, int pos);
在某些情况下,我们需要为图片添加动画效果,比如在用户操作之后,将图标转换成另一张图标。Android 提供了多张方案为 Drawable 添加动画。首先就是使用 AnimationDrawable ,这种方案通过指定多张静态的 Drawable 图片文件组合在一起构成动画(每个时刻只显示一张图片)。另一种就是使用 AnimatedVectorDrawable,这种方案是通过改变矢量图片的属性实现动画。
二、使用 AnimationDrawable
Android提供了动力学动画(DynamicAnimation)的支持,这类动画带有物理动力学的相关特性(而不是硬生生的变化),其中弹簧动画(SpringAnimation)就是一种。顾名思义,弹簧动画就是符合弹簧收缩特性的动画。
一、属性动画简介
Android 中动画有很多种,属性动画就是其中的一种。所谓的属性动画,就是在指定的时间内,通过改变对象的属性达到变化效果的动画。在 Android 中,属性动画系统是一个强健的框架,几乎可以为任何内容添加动画效果。实现属性动画也是通过 Android 的属性动画系统实现,开发者只需要定义动画的一些属性即可完成,这些属性如下:
时长(duration):指定动画的时长。默认时长为 300 毫秒。
时间插值(interpolator):指定如
在前面章节中,提到了 使用 AnimatorSet 编排多个动画,通过 AnimatorSet 可以直接为一个目标对象的多个属性添加动画效果。对于实现由多个属性共同组成的动画效果,还有一种更优的方案,那就是 ViewPropertyAnimator。
二、使用 ViewPropertyAnimator 实现多属性动画效果
ViewPropertyAnimator 有助于使用单个底层 Animator 对
要在 Android 中实现显示和隐藏布局动画,可以使用以下方法:
1. 通过布局属性设置动画:在布局文件中设置 `android:animateLayoutChanges="true"` 属性,这样当布局变化时,Android 将自动为您处理动画效果。
2. 使用 ViewPropertyAnimator:使用 ViewPropertyAnimator 可以实现简单的渐变、平移、缩放等动画效果。例如,以下代码可以实现一个简单的渐变动画:
// 显示布局
layout.setVisibility(View.VISIBLE);
layout.animate().alpha(1.0f);
// 隐藏布局
layout.animate().alpha(0.0f).withEndAction(new Runnable() {
@Override
public void run() {
layout.setVisibility(View.GONE);
3. 使用 LayoutTransition:LayoutTransition 可以为视图容器添加动画效果,包括添加、移除、更改视图等操作。例如,以下代码可以实现一个简单的淡入淡出效果:
// 创建 LayoutTransition 对象
LayoutTransition transition = new LayoutTransition();
// 设置淡入淡出动画
ObjectAnimator fadein = ObjectAnimator.ofFloat(null, "alpha", 0f, 1f);
ObjectAnimator fadeout = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
transition.setAnimator(LayoutTransition.APPEARING, fadein);
transition.setAnimator(LayoutTransition.DISAPPEARING, fadeout);
// 将 LayoutTransition 应用到容器
ViewGroup container = findViewById(R.id.container);
container.setLayoutTransition(transition);
希望这些方法可以帮助你实现显示和隐藏布局动画。