平滑进度栏动画

时间:2015-06-10 20:32:53

标签: android animation progress-bar

我正在尝试为ProgressBar实现平滑动画,但是当我增加时间(30秒)时,动画就不再平滑了。

5秒示例:

5 seconds

30秒示例:

30 seconds

我的进展背景:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <padding android:top="1dp" />
            <solid android:color="#10444444" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" />
            <solid android:color="#20444444" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" />
            <solid android:color="#30444444" />
        </shape>
    </item>
    <item android:id="@android:id/background">
        <shape>
            <solid android:color="@color/black_thirty" />
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <solid android:color="#3500D0" />
            </shape>
        </clip>
    </item>
</layer-list> 

我的进度布局:

<ProgressBar
    android:id="@+id/pb_loading"
    android:layout_width="match_parent"
    android:layout_height="8dp"
    android:indeterminate="false"
    android:layout_centerInParent="true"
    android:progress="100"
    android:progressDrawable="@drawable/my_progress_bar" />

我的动画方法:

private void startAnimation(){
    ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.pb_loading);
    ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 100, 0);
    progressAnimator.setDuration(30000);
    progressAnimator.setInterpolator(new LinearInterpolator());
    progressAnimator.start();
}

9 个答案:

答案 0 :(得分:23)

因为您使用ofInt,所以只能以完整整数移动。换句话说,如果您有一个宽度为1000且进度为0到100的进度条,因为您以整数速度移动,则计算1,2,3,4,这将转换为10px,20px,30px和40px。这解释了你所看到的锯齿状。

要纠正此问题,您有几个选择。第一个是将整数从0增加到someBigInt这将为动画师提供更多数字。

ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 10000, 0);

另一种选择是使用ofFloat,其作用与ofInt相同,但使用浮点而不是整数。

ObjectAnimator progressAnimator = ObjectAnimator.ofFloat(mProgressBar, "progress", 100.0, 0.0);

答案 1 :(得分:18)

如果每次更改进度值1(例如从45到46),您将看不到动画。你最好将进度改变100点(或者其他),为此你只需要将你的最大值乘以100,每个进度值也要增加到100。例如:

    private void setProgressMax(ProgressBar pb, int max) {
        pb.setMax(max * 100);
    }

    private void setProgressAnimate(ProgressBar pb, int progressTo) 
    {
        ObjectAnimator animation = ObjectAnimator.ofInt(pb, "progress", pb.getProgress(), progressTo * 100);
        animation.setDuration(500);
        animation.setInterpolator(new DecelerateInterpolator());
        animation.start();
    }

答案 2 :(得分:6)

刚刚开始 android:max="1000" 并做  ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 1000, 0);

在这种情况下,您将在每个步骤中以1/1000为动画,在默认的100%比例下,在10倍的时间内平滑。它看起来好多了

答案 3 :(得分:3)

XML

       <ProgressBar
        android:id="@+id/progress_bar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="4dp"
        android:indeterminate="false"
        android:progress="0"
        android:max="100"/>

JAVA

@BindView(R.id.progress_bar) ProgressBar progressBar;
ObjectAnimator.ofInt(progressBar, "progress", 79).start();
  

79

  • 此示例中0到100之间的任何数字

答案 4 :(得分:2)

您可以使用ofFloat,因为ProgressBar的progress属性不接受浮点值,只接受整数值。这就是为什么你的ProgressBar在使用该解决方案后停止了进展。

正如其他人所说的那样,正确的做法是将android:max设置为一个大整数。

很抱歉恢复这个帖子,但我觉得必须这样说。

答案 5 :(得分:0)

使用该库可能会帮助您提供填充进度条的时间,它非常流畅,没有任何延迟,但您可以自定义使用它。

只需将依赖项添加到build.gradle:

compile 'com.carlosmuvi.segmentedprogressbar:library:0.2'

接下来,将其添加到您的布局

  <com.carlosmuvi.segmentedprogressbar.SegmentedProgressBar
      android:id="@+id/segmented_progressbar"
      android:layout_width="match_parent"
      android:layout_height="5dp"/>

最后,以编程方式自定义并播放它!

segmentedProgressBar = (SegmentedProgressBar) findViewById(R.id.segmented_progressbar);

// number of segments in your bar
segmentedProgressBar.setSegmentCount(7); 

//empty segment color
segmentedProgressBar.setContainerColor(Color.BLUE); 
//fill segment color
segmentedProgressBar.setFillColor(Color.GREEN); 

//play next segment specifying its duration
segmentedProgressBar.playSegment(5000);

//pause segment
segmentedProgressBar.pause();

//set filled segments directly
segmentedProgressBar.setCompletedSegments(3);

GoToLibrary

答案 6 :(得分:0)

这里是我的倒数计时器的片段,使用流畅的动画,您可以根据需要修改,请按照以下说明:

private void setProgressBarValues() {
        progressBarCircle.setMax((int) (timeCountInMilliSeconds / 10));
        progressBarCircle.setProgress((int) (timeCountInMilliSeconds / 10));
        Log.e("progres", "" + (timeCountInMilliSeconds / 10));
    }

private void startCountDownTimer() {

        smoothAnimation = ObjectAnimator.ofInt(progressBarCircle, "progress", progressBarCircle.getProgress(), progressBarCircle.getMax());
        smoothAnimation.setDuration(500);
        smoothAnimation.setInterpolator(new AccelerateInterpolator());

        countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 10) {
            @Override
            public void onTick(long millisUntilFinished) {

                Log.e("getMax", "" + progressBarCircle.getMax());
                Log.e("getprogres", "" + progressBarCircle.getProgress());
                textViewTime.setText(hmsTimeFormatter(millisUntilFinished));
                progressBarCircle.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
            }

            @Override
            public void onFinish() {

                textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
                // call to initialize the progress bar values
                setProgressBarValues();
                // hiding the reset icon
                buttonReset.setEnabled(false);
                // making edit text editable
                editTextMinute.setEnabled(true);
                // changing the timer status to stopped
                status = TimerStatus.STOPPED;
                smoothAnimation.end();
            }

        }.start();
        smoothAnimation.start();
        countDownTimer.start();
    }

要点:

  1. setMax和setProgress

  2. setAnimation从progess显示进度条的最大值

  3. 创建一个回调为~10毫秒的计时器

  4. 更新onTick的进度,即总计 - 已完成

答案 7 :(得分:0)

您可以像这样制作自定义分类:

dishes: Dish[] = DISHES;

答案 8 :(得分:0)

如果您使用的是Android N及更高版本,则可以使用:

progressBar.setProgress(newProgress, true)

文档:

  

将当前进度设置为指定值,可以选择设置动画   当前值和目标值之间的视觉位置。

     

动画不会影响getProgress()的结果,该结果将   调用此方法后立即返回目标值。

https://developer.android.com/reference/android/widget/ProgressBar.html#setProgress(int,%20boolean)