属性动画的两种实现方法

本文介绍两种在Android中实现复杂动画组合与循环播放的方法。一种是通过AnimatorSet组合多个动画并利用Handler实现循环;另一种则采用Keyframe与PropertyValuesHolder精细控制动画帧,同时设置无限循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一:根据数据processList解析出totalTime,使用AnimatorSet 来组合动画,并把每一组动画加入animations 进行管理。
private float totalTime = 0;
private List<AnimatorSet> animations = new ArrayList<>();
private void createAnim(QZTextView textview, List<FrontPage.FrontPageText.TextProcess> processList) {
    if(textview != null && processList != null){
        List<Animator> sets = new ArrayList<>();
        int totalTime = 0;
        for(int i = 0; i < processList.size(); i++){
            FrontPage.FrontPageText.TextProcess process = processList.get(i);
            totalTime += process.cost;
            ObjectAnimator animatorX = ObjectAnimator.ofFloat(textview, "scaleX", process.start, process.end).setDuration((long) (process.cost * 1000));
            ObjectAnimator animatorY = ObjectAnimator.ofFloat(textview, "scaleY", process.start, process.end).setDuration((long) (process.cost * 1000));
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(animatorX, animatorY);
            sets.add(animatorSet);
        }
        if(totalTime > this.totalTime){//取最长的动画时间
            this.totalTime = totalTime;
        }
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(sets);
        /*animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mHandler.sendEmptyMessageDelayed(1, 2000);
            }
        });*/
        animations.add(animatorSet);
    }
}
AnimatorSet没有循环的方法,所以使用Handler根据totalTime进行 
private Handler mHandler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        for(AnimatorSet animatorset : animations){
            animatorset.start();
        }
        mHandler.sendEmptyMessageDelayed(0, (long) (totalTime * 1000));
        return false;
    }
});
动画创建完之后,使用mHandler.sendEmptyMessage(0);来开始动画,
onRestart和onStop分别开始和取消动画,已经handler的消息。
@Override
protected void onRestart() {
    super.onRestart();
    mHandler.sendEmptyMessage(0);
    for(AnimatorSet animatorset : animations){
        animatorset.start();
    }
}

@Override
protected void onStop() {
    super.onStop();
    mHandler.removeMessages(0);
    for(AnimatorSet animatorset : animations){
        animatorset.cancel();
    }
}
方法二:使用KeyFrame,同样也需要对每一个动画进行管理,如在onDestroy的方法里进行cancel操作。
private void createAnim2(QZTextView textview, List<FrontPage.FrontPageText.TextProcess> processList) {
    float totalTime = 0;
    for (FrontPage.FrontPageText.TextProcess process : processList){
        totalTime += process.cost;
    }
    Keyframe[] keyframes = new Keyframe[processList.size() + 1];
    float cost = 0;
    for (int i = 0; i < processList.size(); i++){
        FrontPage.FrontPageText.TextProcess process = processList.get(i);
        if( i == 0){
            Keyframe f = Keyframe.ofFloat(0, process.start);
            keyframes[0] = f;
        }
        cost += process.cost / totalTime;
        Keyframe f = Keyframe.ofFloat(cost, process.end);
        keyframes[i+1] = f;
    }
    for(int i = 0; i < keyframes.length; i++){
        Log.i("generateText", "Fraction:"+keyframes[i].getFraction() + "---Value" + keyframes[i].getValue());
    }
    PropertyValuesHolder px = PropertyValuesHolder.ofKeyframe("scaleX", keyframes);
    PropertyValuesHolder py = PropertyValuesHolder.ofKeyframe("scaleY", keyframes);
    ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(textview, px, py);
    objectAnimator.setDuration((long) totalTime*1000);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.start();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值