1 官网介绍-google翻译
- 该类在ViewGroup对象的布局更改中启用自动动画。
- 要为布局容器启用transitions ,请创建一个LayoutTransition对象,并通过调用setLayoutTransition(LayoutTransition)将其设置在任何ViewGroup上。这会导致默认动画在items 添加到该容器或从该容器移除时运行。要指定自定义动画,请使用setAnimator()方法。
- transition animations的核心概念之一是,导致转换的变化有两种类型,由于这些变化,有四种不同的动画会运行。
- 触发transition 的更改是将items being added到容器(称为“出现”转换)或removed from容器(也称为“消失”)。设置views的visibility (在*GONE和 VISIBLE之间)将触发相同的添加/删除逻辑。
- 由于这些事件而运行的动画是:1、添加items的动画,2、将被删除items的动画,3、添加/删除发生时更改的容器中的其他items的动画。
- 使用transition 可能需要不同的动画来更改items,具体取决于他们是否因出现或消失的事件而发生变化,因此对于这些变化事件的每个变体都有一个动画。
这个类的大部分API都关心如何设置中的任何一种或全部设置定制动画。
- 默认情况下,DISAPPEARING(消失)和CHANGE_APPEARING(变化出现)动画立即开始。其他动画在延迟设置为默认的动画持续时间后开始。
解释:
当 item is being added to a layout时,该容器的其他子项将首先移动(从而为新项目创建空间),然后显示的动画将运行, item is being added;
当tem is removed from a container时,要移除它的动画将首先运行,然后布局中其他子项的动画将运行(关闭在项目被移除时在布局中创建的间隙)。
- 如果不需要此默认编排行为,则可以根据需要更改任何或所有动画的setDuration(int,long)和setStartDelay(int,long)。
- 注意,如果在DISAPPEARING(消失)动画完成之前启动了APPEARING(显示)动画,则DISAPPEARING(消失)动画将停止,并且会恢复DISAPPEARING动画中的任何效果。如果您在显示动画完成之前启动DISAPPEARING(消失)动画,则会对APPEARING动画发生类似的一组效果。
- 为transition 指定的动画(默认和在转换对象上设置的任何自定义动画)仅为模板。也就是说,这些动画存在的基本动画属性,如持续时间,启动延迟和属性bei
2 Constants
- APPEARING API11
一个标志,子View添加到容器中时的过渡动画效果。画。- CHANGE_APPEARING API11
一个标志,子View添加到容器中时,其他子View位置改变的过渡动画。- CHANGE_DISAPPEARING API11
一个标志,子View从容器中移除时的过渡动画效果。- DISAPPEARING API11
一个标志,子View从容器中移除时,其它子view位置改变的过渡动画- CHANGING API16
一个标志,子View在容器中位置改变时的过渡动画,不涉及删除或者添加操作
3 最简单的布局动画实现
- 只要给子View所在的ViewGroup的xml中添加下面的属性即可:
android:animateLayoutChanges="true"
- 当ViewGroup在添加View时,子View会呈现出过渡的动画效果,这个动画效果是android默认的显示效果,而且无法使用自定义的动画来替换这个效果。
4 LayoutTransition
通过LayoutTransition就可以很容易为ViewGroup在添加或者删除子view设置自定义动画的过渡效果了。
我们可以通过setLayoutTransition()方法为布局容器ViewGroup设置LayoutTransition对象,代码如下:
LayoutTransition mTransitioner = new LayoutTransition();
container.setLayoutTransition(mTransitioner);
public class LayoutAnimationActivity extends Activity {
private int i = 0;
private LinearLayout container;
private LayoutTransition mTransitioner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout_animation);
container = (LinearLayout) findViewById(R.id.container);
mTransitioner = new LayoutTransition();
container.setLayoutTransition(mTransitioner);
setTransition();
}
private void setTransition() {
/**
* 添加View时过渡动画效果
*/
ObjectAnimator addAnimator = ObjectAnimator.ofFloat(null, "rotationY", 0, 90,0).
setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING));
mTransitioner.setAnimator(LayoutTransition.APPEARING, addAnimator);
/**
* 移除View时过渡动画效果
*/
ObjectAnimator removeAnimator = ObjectAnimator.ofFloat(null, "rotationX", 0, -90, 0).
setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING));
mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, removeAnimator);
/**
* view 动画改变时,布局中的每个子view动画的时间间隔
*/
mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);
mTransitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30);
/**
*LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING的过渡动画效果
* 必须使用PropertyValuesHolder所构造的动画才会有效果,不然无效!使用ObjectAnimator是行不通的,
* 发现这点时真特么恶心,但没想到更恶心的在后面,在测试效果时发现在构造动画时,”left”、”top”、”bottom”、”right”属性的
* 变动是必须设置的,至少设置两个,不然动画无效,问题是我们即使这些属性不想变动!!!也得设置!!!
* 我就问您恶不恶心!,因为这里不想变动,所以设置为(0,0)
*
*/
PropertyValuesHolder pvhLeft =
PropertyValuesHolder.ofInt("left", 0, 0);
PropertyValuesHolder pvhTop =
PropertyValuesHolder.ofInt("top", 0, 0);
PropertyValuesHolder pvhRight =
PropertyValuesHolder.ofInt("right", 0, 0);
PropertyValuesHolder pvhBottom =
PropertyValuesHolder.ofInt("bottom", 0, 0);
/**
* view被添加时,其他子View的过渡动画效果
*/
PropertyValuesHolder animator = PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f, 1);
final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(
this, pvhLeft, pvhBottom, animator).
setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_APPEARING));
mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);
/**
* view移除时,其他子View的过渡动画
*/
PropertyValuesHolder pvhRotation =
PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f, 1);
final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(
this, pvhLeft, pvhBottom, pvhRotation).
setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);
}
public void addView(View view) {
i++;
Button button = new Button(this);
button.setText("布局动画_" + i);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
container.addView(button, Math.min(1, container.getChildCount()), params);
}
public void removeView(View view) {
if (i > 0)
container.removeViewAt(0);
}
}
注意
在使用PropertyValuesHolder时,需要注意一下几点:
- 1.LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING必须使用PropertyValuesHolder构造动画才会有效果,其他任何方式构造动画都不会有效果。
- 2.在使用PropertyValuesHolder时,”left”、”top”属性就算不需要变化也必须要写,如果不需要变化可以写成:
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 0);
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 0);
- 3.ofInt,ofFloat中的参数值,第一个值和最后一个值必须相同,不然此属性所对应的的动画将被放弃,在此属性值上将不会有效果
PropertyValuesHolder pvhTranslationY = PropertyValuesHolder
.ofFloat("translationX", 0, 150, 0);
- 4.使用的ofInt,ofFloat中,如果所有参数值都相同,也将不会有动画效果。
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 0);
网友评论