15

我有一个带有 4 个搜索栏的屏幕(如下图所示)。如果用户移动 B、C 或 DI,则计算三者的平均值并将 A 的 setProgress 设置为平均值。那是容易的部分。我想做的是为进度条 A 设置动画,使其不会一次跳跃(例如从 25-75 )。

动画 A 的推荐方法是什么?我得到了一个简单的动画,但我每 50 毫秒调用一次 TimerTask 以将 A 增加或减少一个单位值,直到达到所需的位置。但它的效率不是很高。

注意:我有一个自定义 Seekbar 对象,我使用它创建了 seekBar 的 A、B、C 和 D。抱歉,我不能真正分享代码,但很乐意澄清任何事情。

在此处输入图像描述

4

6 回答 6

20

我想为时已晚。但我找到了一种使用 ValueAnimator 实现此目的的方法。

ValueAnimator anim = ValueAnimator.ofInt(0, seekBar.getMax());
anim.setDuration(1000);
anim.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    int animProgress = (Integer) animation.getAnimatedValue();
    seekBar.setProgress(animProgress);
    }
});
anim.start();
于 2013-06-12T20:33:36.267 回答
5

我已经使用ObjectAnimator.

private void animateProgression(int progress) {
    final ObjectAnimator animation = ObjectAnimator.ofInt(mySeekBar, "progress", 0, progress);
    animation.setDuration(3000);
    animation.setInterpolator(new DecelerateInterpolator());
    animation.start();
    mySeekBar.clearAnimation();
}
于 2018-03-13T17:08:18.230 回答
2

这适用于任何 Android 版本,无需使用任何动画。

private void animateSeek(final SeekBar mSeek, final int toVal) {
    new Thread(new Runnable() {
        @Override
        public void run() {

            while (true) {
                if (mSeek.getProgress() == toVal) {
                    break;
                }
                int mProgress = mSeek.getProgress();
                if (mProgress < toVal) {
                    mProgress++;

                } else if (mProgress > toVal) {
                    mProgress--;
                }

                mSeek.setProgress(mProgress);

                try {
                    Thread.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}
于 2016-10-03T13:41:58.463 回答
1

我需要的代码就像@sidhanshu_udawat 所做的那样。这是一个很好的起点。大获全胜,因为它在自己的线程上运行。谢谢你的例子。

但是,当我使用该代码并尝试它时,会出现一个问题,即它会增加然后停止。

我更改了代码(粘贴在下面),现在如果您使用如下代码发送搜索栏,您将看到搜索栏上下动画。

isRunning - 控制您的活动

此外,当有人单击按钮时,我需要停止动画,因此我将布尔值 isRunning 添加为我的 Activity 的成员。现在,当他们单击按钮时,我将 isRunnig 设置为 false 并且 SeekBar 停止。

如下设置您的 SeekBar,然后调用该方法:

animSeekBar.incrementProgressBy(1);
  animSeekBar.setMax(100);
  animateSeek(animSeekBar,100);

private void animateSeek(final SeekBar mSeek, final int toVal) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                boolean isIncrementing = true;
                int mProgress = 0;
                isRunning = true;

                while (isRunning) {
                    if (isIncrementing){
                        mProgress++;
                    }
                    else{
                        mProgress--;
                    }
                    mSeek.setProgress(mProgress);
                    if (mProgress >= toVal) {
                        isIncrementing = false;

                    } else if (mProgress <= 0) {
                        isIncrementing = true;
                    }
                    try {
                        Thread.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
于 2017-05-12T19:16:37.730 回答
0

如果您使用的是 Honeycomb,那么您可以使用 ViewPropertyAnimator http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html

3.0 之前的动画非常有限,但作为您的方法的替代方法,您可以使用动画侦听器:

anim.setAnimationListener(new AnimationListener() {
  public void onAnimationStart(Animation anim) {
     //moveseekbar
  }
  public void onAnimationRepeat(Animation anim) {}
  public void onAnimationEnd(Animation anim) {
     //call animation again if movement not complete
  }
});   

不要忘记调用 setFillAfter(boolean fillAfter) 因为动画 <3.0 实际上并没有移动视图。它只是给人一种视图已经移动的错觉。如果您仍然希望搜索栏继续接收触摸,重要的区别。

于 2011-06-05T14:47:58.907 回答
-1

我通过在指数函数而不是单位增量上迭代计时器任务来减少迭代次数。仍然希望得到更好的答案:-)

于 2011-06-05T16:39:42.220 回答