我正在尝试为ProgressBar
实现平滑动画,但是当我增加时间(30秒)时,动画就不再平滑了。
5秒示例:
30秒示例:
我的进展背景:
<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();
}
答案 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)
<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"/>
@BindView(R.id.progress_bar) ProgressBar progressBar;
ObjectAnimator.ofInt(progressBar, "progress", 79).start();
79
答案 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);
答案 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();
}
要点:
setMax和setProgress
setAnimation从progess显示进度条的最大值
创建一个回调为~10毫秒的计时器
更新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)