android动画监听不跑onanimationrepeat,Android属性动画

1.ObjectAnimatorObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 300);

animator.setDuration(1000);

animator.start();

常用的属性动画的属性值:

translationX和translationY:这两个属性作为一种增量来控制着View对象从它布局容器的左上角坐标偏移位置

rotation、rotationX和rotationY:这三个属性控制View对象围绕支点进行2D和3D旋转

scaleX和scaleY:这两个属性控制着View对象围绕它的支点进行2D缩放

pivotX和pivotY:这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,该支点的位置就是View对象的中心点

x和y:描述了View对象在它容器中的最终位置,它是最初的左上角坐标translationX、translationY值的累计和

alpha:它表示View对象的aplha透明度。默认值是1不透明,0代表完全透明

要操纵的属性必须具有get、set方法,不然ObjectAnimator就无法起效。可以通过自定义一个属性类或者包装类,来间接地给这个属性增加get、set方法private static class WrapperView {

private View mTarget;

public WrapperView(View target) {

this.mTarget = target;

}

public int getWidth() {

return mTarget.getLayoutParams().width;

}

public void setWidth(int width) {

mTarget.getLayoutParams().width = width;

mTarget.requestLayout();

}

}

通过以上代码,就给一个属性包装了一层,并给他技工了get、set方法。使用时只需要操纵包装类就可以间接调用get、set方法了,代码如下:public void btnButton(View view) {

WrapperView wrapperView = new WrapperView(view);

ObjectAnimator.ofInt(wrapperView, "width", 500).setDuration(1000).start();

}

2.PropertyValuesHolder

类似视图动画中的AnimationSet,在属性动画中,如果针对一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder来实现。比如在平移的过程中,同时改变X、Y轴的缩放,可以这样实现:public void btnButton(View view) {

PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 300F);

PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleX", 1F, 0F, 1F);

PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("scaleY", 1F, 0F, 1F);

ObjectAnimator.ofPropertyValuesHolder(view, p1, p2, p3).setDuration(1000).start();

}

在代码中,分别使用PropertyValuesHolder对象来控制translationX scaleX scaleY这三个属性,最后调用ObjectAnimator.ofPropertyValuesHolder()方法实现多属性动画的共同作用,整个实现方法非常类似AnimationSet是使用

3.ValueAnimator

ObjectAnimator继承自ValueAnimator,ValueAnimator本身不提供任何动画效果,它更像一个数值发生器,用来产生具有一定规律的数字,从而让调用者来控制动画的实现过程,ValueAnimator的一般使用方法如下:public void btnButton(View view) {

final Button button = (Button) view;

ValueAnimator animator = ValueAnimator.ofInt(0, 100);

animator.setDuration(5000);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

Integer value = (Integer) animation.getAnimatedValue();

button.setText("" + value);

}

});

animator.start();

}

通过ValueAnimator生成0~100的“渐变”数字,并将数字设置到Button上,从而使得Button显示0~100的数字,具有动画的效果

4.动画事件的监听

一个完整的动画具有start repeat end cancel四个过程,通过Android提供的接口,可以很方便监听这四个事件:public void btnButton(View view) {

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0F, 1F);

animator.setDuration(1000);

animator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

Toast.makeText(Main2Activity.this, "anim end", Toast.LENGTH_SHORT).show();

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

animator.start();

}

当然,大部分时候,我们只关心onAnimationEnd事件,所以Android也提供了一个AnimatorListenerAdapter来让我们选择必要的事件进行监听,代码如下:animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

Toast.makeText(Main2Activity.this, "anim end", Toast.LENGTH_SHORT).show();

}

});

5.AnimatorSet

对于一个属性同时作用多个属性动画效果,前面已经用PropertyValuesHolder实现了这样的效果。而AnimatorSet不仅能实现这样的效果,同时也能实现更为精确的顺序控制。同样是实现上面使用PropertyValuesHolder演示的那个动画效果,如果使用AnimatorSet实现如下:public void btnButton(View view) {

ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300F);

ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1F, 0F, 1F);

ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1F, 0F, 1F);

AnimatorSet set = new AnimatorSet();

set.setDuration(1000);

//        set.playTogether(animator1, animator2, animator3);

//        set.playSequentially(animator1, animator2, animator3);

set.play(animator2).with(animator3);

set.play(animator1).after(animator3);

set.start();

}

在属性动画中,AnimatorSet正是通过playTogether()、playSequentially()、set.play().with()、before()、after()这些方法来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。

7.插值器Interpolator

插值器是动画中一个非常重要的概念,通过插值器Interpolator可以定义动画变换速率

eb193141d2aed7d575bc5fe5ad58c852.png

下面这个例子,通过设置插值器animator.setInterpolator(new BounceInterpolator())使得每个ImageView在动画停止时有一个小球弹跳的效果

159743f3c70b6140f5409a4fe92836f1.gifpublic class Main3Activity extends AppCompatActivity implements View.OnClickListener {

private int[] res = {R.id.imageView_a, R.id.imageView_b, R.id.imageView_c, R.id.imageView_d,

R.id.imageView_e, R.id.imageView_f, R.id.imageView_g, R.id.imageView_h,};

private List imageViewList = new ArrayList<>();

private boolean flag = true;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main3);

for (int i = 0; i 

ImageView imageView = findViewById(res[i]);

imageView.setOnClickListener(this);

imageViewList.add(imageView);

}

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.imageView_a:

if (flag) {

startAnim();

} else {

closeAnim();

}

break;

default:

Toast.makeText(this, "click" + v.getId(), Toast.LENGTH_SHORT).show();

break;

}

}

private void closeAnim() {

for (int i = 1; i 

ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),

"translationY", i * 100F, 0F);

animator.setDuration(1000);

// 设置插值器

animator.setInterpolator(new BounceInterpolator());

animator.setStartDelay(i * 100);

animator.start();

flag = true;

}

}

private void startAnim() {

for (int i = 1; i 

ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),

"translationY", 0F, i * 100F);

animator.setDuration(1000);

// 设置插值器

animator.setInterpolator(new BounceInterpolator());

animator.setStartDelay(i * 200);

animator.start();

flag = false;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值