自定义View之动画篇(十二)-ViewPropertyAnimator

ViewPropertyAnimator

android 3.0虽然引入的属性动画,既能针对一些系统定义的属性如setAphla()、setScale()做动画,也能自定义属性;我们日常使用中存储需要为这些默认的属性设置动画,但通过属性动画使用显得很繁琐不人性化,于是android 3.1补充了ViewPropertyAnimator这个机制;

	ViewPropertyAnimator animator=view.animator();
	animator.alpha(0f);

通过ViewProertyAnimator对象的函数来设置需要实现动画的属性,同时也不需要像之前的属性动画调用start()方法开始动画,它是自动开始的(隐式启动的);

关于ViewPropertyAniamtor常用函数

	//设置透明度
	alpha(float value)
	//设置Y轴方向缩放
	scaleY(float value)
	scaleX(float value)

	//X轴方向的移动值
	translationX(...)
	translationY()

	rotationX(...)
	rotationY()
	
	//相对于父容器的左上角坐标在X的的最终位置
	x(float value)
	//相对于父容器的左上角的坐标在Y轴的方向的最终位置
	y(float vlaue)

	//设置透明度增量
	alphaBy(float value)
	rotationBy(float value)
	rotationXBy()
	rotationYBy()
	translationXBy()
	translationYBy()
	scaleXBy()
	scaleYBy()
	xBy()
	yBy()

	setInterpolator(TimeInterpolator interpolator)
	setStartDelay(long startDelay)
	setDuration(long duration)

这里主要说一下x(float value)对应android 3.0中新增加的setX(float value),用于将控件移动到指定位置;这个位置是以父容器左上角为坐标原点的;

和属性动画一样,也可以设置监听器如:

	view.animate().scaleY(2).setListener(new Animator.AnimatorListener(){
		
			public void onAimationStart(Animator aniamtor){

			}

			public viod onAnimationEnd(Animator animator){


			}

			.......



	});

性能的提升

和ObjectAnimator不同的是,ViewPropertyAnimator没有使用反射或者JNI技术,而是根据预设的每一个动画帧计算出对应的所有属性值,并设置给控件,然后调用一次invalidate()函数进行重绘,从而解决了使用ObjectAnimator时每个属性单独计算、单独重绘的问题;

  1. ObjectAnimator构建动画过程相对于ViewpropertyAnimator根繁琐
  2. 同时为View多个属性做动画时,后者更方便;

为ViewGroup中的组件添加动画

前面讲的ValueAnimator、ObjectAnimator、AnimatorSet都只能针对一个控件做动画,如果要实现对ViewGroup中的所有控件统一做入场、出厂动画等,是无法实现的;比如:为ListView的item入场、出场、数据变更是添加动画;

android提供了四种方法:

  1. layoutAnimation标签与LayoutAnimationController

android:layoutAnimation:标签在API1就引入,专门针对ListView添加入场动画所使用的,后者为其代码实现,它可以在ListView创建时对其中的每个Item添加入场动画,而且动画可以自定义;缺点:ListView创建完成后,如果在添加数据,则新添加的数据不会有入场动画;

  1. gridLayoutAnimation标签与GridLayoutAnimationController

专门针对GridView添加入场动画的,和上面的大同小异,gridView创建完成后,在添加数据,新添加的数据不会有入场动画;

  1. android:animatedLayoutChanged=false/true属性

所有派生自ViewGroup的控件都具有此属性,只要在布局文件中添加这个属性,就能实现添加、删除其中控件时带有的默认动画,缺点:该动画不能自定义;

  1. LayoutTransition

android API 11引入,实现ViewGroup动态添加或者删除控件动画,动画可以自定义

LayoutTransition

上面四种方式,无疑LayoutTransition是最强大的,我们看看如何使用:

  1. 创建实例

  2. 创建动画并进行设置

  3. 将layoutTransition设置到ViewGroup

     	LayoutTransition transitioner=new LayoutTransition();
     	
     	ObjectAniamtor animator=ObjectANimator.ofFloat(null,"rotation",0f,90f,0f);
     	transitioner.setAnimatior(LayoutTransition.DISAPPEARING,animtor);
    
     	vp.setLayoutTransition(transition);
    

需要注意的就是:setAnimator(int transitionType,Animator animator);

第一个参数取值:

APPEARING:元素在容器中出现时定义的动画;
DISAPPEARING:元素在容器中消失时所定义的动画
CHANGE_APPEARING:容器中要显示一个新的元素,其他元素需要变化的元素所应用的动画
CHANGE_DISAPPEARING:容器中某个元素消失时,其他需要变化的元素所应用的动画

这里ChANGE_APPEARING和CHANGE_DISAPPEARING在使用时有许多坑:

  1. 必须使用PropertyValuesHolder构造的动画才有效果,使用ObjectAnimator构造的动画没有效果;
  2. 在构造PropertyValuesHolder动画时,“left”、"top"属性的变动是必须的写,即使不需要变动也要写即:PropertyValuesHolder holderLeft=PropertyValuesHolder.ofInt(“left”,0,0);PropertyValuesHolder holderTop=PropertyValuesHolder.ofInt(“top”,0,0);
  3. 在构造PropertyValuseHolder动画时,所有ofInt、ofFloat()参数值第一个和最后一个必须相同,否则此属性的动画将会被放弃,得不到效果;

这里简单演示下往LinearLayout中添加和删除控件动画效果:

 PropertyValuesHolder valuesHolder = PropertyValuesHolder.ofObject("textCharacter", new CharacterEvaluator(), new Character('A'), new Character('Z'));
        animator = ObjectAnimator.ofPropertyValuesHolder(view, valuesHolder);
        animator.setDuration(20000);
        PropertyValuesHolder holder1= PropertyValuesHolder.ofFloat("scaleX", 1f, 0.5f, 1f);
        PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("rotation", 0, 90f, 150f, 360, 0f);
        PropertyValuesHolder holder = PropertyValuesHolder.ofInt("left", 0, 0);
        PropertyValuesHolder holder3 = PropertyValuesHolder.ofInt("top", 0, 0);
        ValueAnimator animatorIn = ObjectAnimator.ofPropertyValuesHolder(mContainer,holder1,holder,holder3);
        ValueAnimator animatorOut = ObjectAnimator.ofPropertyValuesHolder(mContainer,holder2,holder,holder3);

        LayoutTransition transition = new LayoutTransition();
        transition.setDuration(2000);

        transition.setAnimator(LayoutTransition.CHANGE_APPEARING,animatorIn);
        transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,animatorOut);
        mContainer.setLayoutTransition(transition);



		.....


		case R.id.add:
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            Button button = new Button(this);
            int i = new Random().nextInt(10);
            button.setText(""+i);
            button.setTextSize(40);

            mContainer.addView(button,0,params);

            break;
        case R.id.dis:
            mContainer.removeViewAt(0);
            break;

TransitionLayout的函数

//设置所有动画完成需要的时长
setDuration(long duration);

//针对APPEARING等单个设置时长
setDuration(int transitionType,long duration)

//针对单个Type设置插值器

setInterpolator(int transitionType,TimeInterpolator interpolator)

//针对每个Type设置每个item动画的时间间隔
public void setStagger(int transitionType,long duration)

setDurationDelay(int transitionType,long delay)

同时也提供了监听函数

public void addTransitionListener(TransitionListener listener)


public interface TransitionListener {

        
		//container:当前应用LayoutTransition的容器
		//view:当前在做动画的View
        public void startTransition(LayoutTransition transition, ViewGroup container,View view, int transitionType);

        
        public void endTransition(LayoutTransition transition, ViewGroup container,View view, int transitionType);
    }

就以上面的动画为例,这里的view应该是LinearLayout,如果是APPEARING、DISAPPEARING类型,那么这里View就变成了添加或者删除的那个View了;

sition(LayoutTransition transition, ViewGroup container,View view, int transitionType);
}

就以上面的动画为例,这里的view应该是LinearLayout,如果是APPEARING、DISAPPEARING类型,那么这里View就变成了添加或者删除的那个View了;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值