属性动画代码及布局
2017-11-13 21:14
141 查看
布局中
anim下面的
alpha.xml
scale.xml
animator下面的
animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="2.0"
android:valueType="floatType">
</objectAnimator>animator1.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<!--together一起-->
<!--sequentially表示一个接一个执行-->
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0.5">
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0.5">
</objectAnimator>
</set>
MainActivity.java
public class MainActivity extends AppCompatActivity {
float screenHeight = 1000;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
screenHeight = wm.getDefaultDisplay().getHeight();
imageView = (ImageView) findViewById(R.id.image_anim);
//图片的点击事件
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println("v = " + view.getX() + " " + view.getY());
}
});
//执行动画 按钮的点击事件
Button exe_btn = (Button) findViewById(R.id.exe_btn);
exe_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//点击按钮调用不同的方法
//rotateAnim();
// loadxml1();
// loadxml2();
//translateAnimation();
// rotateAnim(imageView);
rotateAnim1(imageView);
}
});
}
//一系列的方法,需要调用
public void rotateAnim(View view){
/**
* view 需要执行动画的view
* rotationY view 所具有的属性
* 0,360f 可变参数 0度旋转到360度
*/
ObjectAnimator.ofFloat(view,"rotationY",0,360f)
.setDuration(3000)
.start();
}
public void rotateAnim1(final View view){
ObjectAnimator objectAnimator = new ObjectAnimator()
.ofFloat(view,"rotationX",0,360f)
.setDuration(500);
objectAnimator.start();
//动画执行过程中的监听
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
System.out.println("animation = " + valueAnimator.getAnimatedValue());
float val = (float) valueAnimator.getAnimatedValue();
view.setAlpha(val);
view.setScaleX(val);
view.setScaleY(val);
}
});
}
private void propertyValues(View view){
PropertyValuesHolder propertyValuesHolderalpha = PropertyValuesHolder.ofFloat("alpha",1.0f,0.0f,1.0f) ;
PropertyValuesHolder propertyValuesHolderalScaleX = PropertyValuesHolder.ofFloat("scaleX",1.0f,0.0f,1.0f) ;
PropertyValuesHolder propertyValuesHolderalScaleY = PropertyValuesHolder.ofFloat("scaleY",1.0f,0.0f,1.0f) ;
ObjectAnimator.ofPropertyValuesHolder(view,propertyValuesHolderalpha,propertyValuesHolderalScaleX,propertyValuesHolderalScaleY).setDuration(500).start();
// ObjectAnimator anim = new ObjectAnimator();
// anim.setTarget(view);
// anim.setValues(propertyValuesHolderalScaleX,propertyValuesHolderalpha,propertyValuesHolderalScaleY);
// anim.setDuration(300);
// anim.start();
}
//值动画
public void ValueAnimator1(View view){
//构造一个 ValueAnimator 对象
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,600);
//为 ValueAnimator 设置需要执行动画的view
valueAnimator.setTarget(imageView);
valueAnimator.setDuration(1000).start();
//执行过程中的监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
System.out.println("animation = " + animation.getAnimatedValue());
//通过 setTranslationY 改变view 的位置
imageView.setTranslationY((Float) animation.getAnimatedValue());
}
});
}
// 值动画
public void ValueAnimator2(View view) {
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(3000);
valueAnimator.setObjectValues(new PointF(0,0));
// http://doc.okbase.net/qiujuer/archive/122469.html // 插值器
valueAnimator.setInterpolator(new LinearInterpolator());
// 计算属性值的,即可计算任意类型的值。//估值器
valueAnimator.setEvaluator(new TypeEvaluator<PointF>()
{
// fraction = t / duration
//fraction 当前运行的时间比上总持续时间的 比值(中间经过插入器的规则运算)
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue)
{
System.out.println("fraction = " + fraction);
// x方向200px/s ,则y方向0.5 * 10 * t
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
PointF point = (PointF) animation.getAnimatedValue();
imageView.setX(point.x);
imageView.setY(point.y);
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
public void animatorSet1(View view){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"scaleX",1.0f,2.0f);
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view,"scaleY",1.0f,2.0f);
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(2000);
animationSet.setInterpolator(new LinearInterpolator());
// playTogether 多个动画一起执行
animationSet.playTogether(objectAnimator, objectAnimator1);
animationSet.start();
}
public void animatorSet2(View view){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"scaleX",1.0f,2.0f);
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view,"scaleY",1.0f,2.0f);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view,"x",view.getX(),200f);
ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view,"y",view.getY(),200f);
AnimatorSet animatorSet = new AnimatorSet();
//**
// * anim1,anim2,anim3同时执行
// * anim4接着执行
// */
animatorSet.play(objectAnimator).with(objectAnimator1);
animatorSet.play(objectAnimator1).with(objectAnimator2);
//objectAnimator3 执行完 在执行objectAnimator2
animatorSet.play(objectAnimator2).after(objectAnimator3);
animatorSet.setDuration(1000);
animatorSet.start();
}
//调用R.animator.animator
public void loadxml1(){
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.animator);
animator.setTarget(imageView);//目标是哪个控件
animator.start();
}
//调用R.animator.animator1
public void loadxml2(){
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.animator1);
animator.setTarget(imageView);//目标是哪个控件
animator.start();
}
public void translateAnimation(){
TranslateAnimation animation = new TranslateAnimation(0,750,0,300);
animation.setDuration(2000);
animation.setRepeatCount(1);
imageView.setAnimation(animation);
animation.startNow();
}
//------------------------------------------
Animation animation;
//一系列的点击事件
//透明度点击
public void alpha(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.alpha);
imageView.startAnimation(animation);
}
//
public void rotate(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.rotate);
imageView.startAnimation(animation);
}
public void scale(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.scale);
imageView.startAnimation(animation);
}
public void translate(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.translate);
imageView.startAnimation(animation);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:id="@+id/image_anim"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="bottom"> <Button android:onClick="alpha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/alphe_id" android:text="alpha"/> <Button android:onClick="rotate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rotate_id" android:text="rotate"/> <Button android:onClick="scale" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/scale_id" android:text="scale"/> <Button android:onClick="translate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/translate_id" android:text="translate"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:text="ValueAnimator2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="ValueAnimator2" android:id="@+id/valueanimator1"/> </LinearLayout> <Button android:text="执行动画" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/exe_btn"/> </LinearLayout>res下面创建文件夹anim , animator
anim下面的
alpha.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:duration = "1000" android:fromAlpha="0.0" android:toAlpha="1.0" /> <!-- 透明度控制动画效果 alpha 浮点型值: fromAlpha 属性为动画起始时透明度 toAlpha 属性为动画结束时透明度 说明: 0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之间的float数据类型的数字 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 --> </set>rotate.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:duration="3000" android:fromDegrees="0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toDegrees="+350" /> <!-- rotate 旋转动画效果 属性:interpolator 指定一个动画的插入器 在我试验过程中,使用android.res.anim中的资源时候发现 有三种动画插入器: accelerate_decelerate_interpolator 加速-减速 动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator 减速- 动画插入器 其他的属于特定的动画效果 浮点数型值: fromDegrees 属性为动画起始时物件的角度 toDegrees 属性为动画结束时物件旋转的角度 可以大于360度 说明: 当角度为负数——表示逆时针旋转 当角度为正数——表示顺时针旋转 (负数from——to正数:顺时针旋转) (负数from——to负数:逆时针旋转) (正数from——to正数:顺时针旋转) (正数from——to负数:逆时针旋转) pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 说明: 以上两个属性值 从0%-100%中取值 50%为物件的X或Y方向坐标上的中点位置 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 --> </set>
scale.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="false" > <scale android:duration="1000" android:fromXScale="0.0" android:fromYScale="0.0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toXScale="1.4" android:toYScale="1.4" /> </set> <!-- 尺寸伸缩动画效果 scale 属性:interpolator 指定一个动画的插入器 在我试验过程中,使用android.res.anim中的资源时候发现 有三种动画插入器: accelerate_decelerate_interpolator 加速-减速 动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator 减速- 动画插入器 其他的属于特定的动画效果 浮点型值: fromXScale 属性为动画起始时 X坐标上的伸缩尺寸 toXScale 属性为动画结束时 X坐标上的伸缩尺寸 fromYScale 属性为动画起始时Y坐标上的伸缩尺寸 toYScale 属性为动画结束时Y坐标上的伸缩尺寸 说明: 以上四种属性值 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大 pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 说明: 以上两个属性值 从0%-100%中取值 50%为物件的X或Y方向坐标上的中点位置 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 布尔型值: fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用 -->translate.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" > <translate android:duration="2000" android:fromXDelta="30" android:fromYDelta="30" android:toXDelta="80" android:toYDelta="500" /> <!-- translate 位置转移动画效果 整型值: fromXDelta 属性为动画起始时 X坐标上的位置 toXDelta 属性为动画结束时 X坐标上的位置 fromYDelta 属性为动画起始时 Y坐标上的位置 toYDelta 属性为动画结束时 Y坐标上的位置 注意: 没有指定fromXType toXType fromYType toYType 时候, 默认是以自己为相对参照物 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 --> </set>
animator下面的
animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="2.0"
android:valueType="floatType">
</objectAnimator>animator1.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<!--together一起-->
<!--sequentially表示一个接一个执行-->
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0.5">
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0.5">
</objectAnimator>
</set>
MainActivity.java
public class MainActivity extends AppCompatActivity {
float screenHeight = 1000;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
screenHeight = wm.getDefaultDisplay().getHeight();
imageView = (ImageView) findViewById(R.id.image_anim);
//图片的点击事件
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println("v = " + view.getX() + " " + view.getY());
}
});
//执行动画 按钮的点击事件
Button exe_btn = (Button) findViewById(R.id.exe_btn);
exe_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//点击按钮调用不同的方法
//rotateAnim();
// loadxml1();
// loadxml2();
//translateAnimation();
// rotateAnim(imageView);
rotateAnim1(imageView);
}
});
}
//一系列的方法,需要调用
public void rotateAnim(View view){
/**
* view 需要执行动画的view
* rotationY view 所具有的属性
* 0,360f 可变参数 0度旋转到360度
*/
ObjectAnimator.ofFloat(view,"rotationY",0,360f)
.setDuration(3000)
.start();
}
public void rotateAnim1(final View view){
ObjectAnimator objectAnimator = new ObjectAnimator()
.ofFloat(view,"rotationX",0,360f)
.setDuration(500);
objectAnimator.start();
//动画执行过程中的监听
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
System.out.println("animation = " + valueAnimator.getAnimatedValue());
float val = (float) valueAnimator.getAnimatedValue();
view.setAlpha(val);
view.setScaleX(val);
view.setScaleY(val);
}
});
}
private void propertyValues(View view){
PropertyValuesHolder propertyValuesHolderalpha = PropertyValuesHolder.ofFloat("alpha",1.0f,0.0f,1.0f) ;
PropertyValuesHolder propertyValuesHolderalScaleX = PropertyValuesHolder.ofFloat("scaleX",1.0f,0.0f,1.0f) ;
PropertyValuesHolder propertyValuesHolderalScaleY = PropertyValuesHolder.ofFloat("scaleY",1.0f,0.0f,1.0f) ;
ObjectAnimator.ofPropertyValuesHolder(view,propertyValuesHolderalpha,propertyValuesHolderalScaleX,propertyValuesHolderalScaleY).setDuration(500).start();
// ObjectAnimator anim = new ObjectAnimator();
// anim.setTarget(view);
// anim.setValues(propertyValuesHolderalScaleX,propertyValuesHolderalpha,propertyValuesHolderalScaleY);
// anim.setDuration(300);
// anim.start();
}
//值动画
public void ValueAnimator1(View view){
//构造一个 ValueAnimator 对象
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,600);
//为 ValueAnimator 设置需要执行动画的view
valueAnimator.setTarget(imageView);
valueAnimator.setDuration(1000).start();
//执行过程中的监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
System.out.println("animation = " + animation.getAnimatedValue());
//通过 setTranslationY 改变view 的位置
imageView.setTranslationY((Float) animation.getAnimatedValue());
}
});
}
// 值动画
public void ValueAnimator2(View view) {
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(3000);
valueAnimator.setObjectValues(new PointF(0,0));
// http://doc.okbase.net/qiujuer/archive/122469.html // 插值器
valueAnimator.setInterpolator(new LinearInterpolator());
// 计算属性值的,即可计算任意类型的值。//估值器
valueAnimator.setEvaluator(new TypeEvaluator<PointF>()
{
// fraction = t / duration
//fraction 当前运行的时间比上总持续时间的 比值(中间经过插入器的规则运算)
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue)
{
System.out.println("fraction = " + fraction);
// x方向200px/s ,则y方向0.5 * 10 * t
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
PointF point = (PointF) animation.getAnimatedValue();
imageView.setX(point.x);
imageView.setY(point.y);
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
public void animatorSet1(View view){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"scaleX",1.0f,2.0f);
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view,"scaleY",1.0f,2.0f);
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(2000);
animationSet.setInterpolator(new LinearInterpolator());
// playTogether 多个动画一起执行
animationSet.playTogether(objectAnimator, objectAnimator1);
animationSet.start();
}
public void animatorSet2(View view){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"scaleX",1.0f,2.0f);
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view,"scaleY",1.0f,2.0f);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view,"x",view.getX(),200f);
ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view,"y",view.getY(),200f);
AnimatorSet animatorSet = new AnimatorSet();
//**
// * anim1,anim2,anim3同时执行
// * anim4接着执行
// */
animatorSet.play(objectAnimator).with(objectAnimator1);
animatorSet.play(objectAnimator1).with(objectAnimator2);
//objectAnimator3 执行完 在执行objectAnimator2
animatorSet.play(objectAnimator2).after(objectAnimator3);
animatorSet.setDuration(1000);
animatorSet.start();
}
//调用R.animator.animator
public void loadxml1(){
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.animator);
animator.setTarget(imageView);//目标是哪个控件
animator.start();
}
//调用R.animator.animator1
public void loadxml2(){
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.animator1);
animator.setTarget(imageView);//目标是哪个控件
animator.start();
}
public void translateAnimation(){
TranslateAnimation animation = new TranslateAnimation(0,750,0,300);
animation.setDuration(2000);
animation.setRepeatCount(1);
imageView.setAnimation(animation);
animation.startNow();
}
//------------------------------------------
Animation animation;
//一系列的点击事件
//透明度点击
public void alpha(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.alpha);
imageView.startAnimation(animation);
}
//
public void rotate(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.rotate);
imageView.startAnimation(animation);
}
public void scale(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.scale);
imageView.startAnimation(animation);
}
public void translate(View view){
animation = AnimationUtils.loadAnimation(this,R.anim.translate);
imageView.startAnimation(animation);
}
}
相关文章推荐
- 利用属性动画轻松实现 Android TV 游标动画,你缺的是几行代码
- 笔记17 Animator 安卓属性动画 仿直线菜单 代码量极少抛弃使用animation
- 浅谈属性动画(上 Java代码实现)
- 布局xml中的属性设置如何在代码中实现
- Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)
- android代码中动态设置布局中控件的属性
- android之属性动画和布局动画详解
- Android动画 实现开关按钮动画(属性动画之平移动画)实例代码
- Android 布局平铺展开效果的属性动画
- android源码分享,布局切换微信提醒对话框下拉刷新Cell进度动画代码下载
- 代码中,控制布局属性(RECT + 位置)
- PullToRefreshListView布局属性及java代码应用
- android属性动画—自己的测试代码
- 安卓属性动画,listview上滑隐藏头部布局
- Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)
- Android属性动画实现布局的下拉展开
- Animation Tween动画可以通过java代码实现,也可以通过xml布局来实现
- silverlight中用代码动态控制Storyboard(动画)属性的几种方法
- 属性动画,代码详细解析
- Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)