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();
}
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(たとえば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();
}
_Android:max="1000"
_を設定し、ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 1000, 0);
するだけです
この場合、各ステップごとに1/1000でアニメーション化され、デフォルトでは100パーセントのスケールで10時間で滑らかになります。そしてそれははるかに良く見える
<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
notを使用できます。ofFloat
を使用するのは、ProgressBarのprogress属性がfloat値を受け入れず、整数値のみを受け入れるためです。そのため、そのソリューションを使用した後、ProgressBarの進行が停止しました。
他の人が言っているように、あなたがしたいことをする正しい方法は、Android:max
いくつかの大きな整数。
スレッドを復活させてすみませんが、これは言わなければならなかったように感じます。
Android N以上の場合、次を使用できます。
progressBar.setProgress(newProgress, true)
ドキュメント:
現在の進行状況を指定した値に設定し、オプションで現在の値とターゲット値の間の視覚的な位置をアニメーション化します。
アニメーションは、このメソッドが呼び出された直後にターゲット値を返すgetProgress()の結果には影響しません。
https://developer.Android.com/reference/Android/widget/ProgressBar.html#setProgress(int、%20boolean)
ライブラリを使用すると、プログレスバーを埋める時間を非常に滑らかに遅らせることができますが、これを使用するために少しカスタマイズします。
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);
以下は、必要に応じて変更できるスムーズなアニメーションを使用したカウントダウンタイマーのスニペットです。
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
〜10ミリ秒のコールバックでタイマーを作成します
onTickの更新の進行状況、つまり合計-終了
次のようなカスタムクラスを作成できます。
public class CustomProgressBar extends ProgressBar {
private static final long DEFAULT_DELAY = 500;
private static final long DEFAULT_DURATION = 1000;
public CustomProgressBar(Context context) {
super(context);
}
public CustomProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public synchronized void setProgress(float progress) {
super.setProgress((int) progress);
}
@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);
}
public void startLcpProgressAnim(int progressTo) {
startLcpProgressAnim(DEFAULT_DELAY, progressTo);
}
public void startLcpProgressAnim(long delay, int progressTo) {
startLcpProgressAnim(DEFAULT_DURATION, delay, progressTo);
}
public void startLcpProgressAnim(long duration, long delay, float progressTo) {
ObjectAnimator animation = ObjectAnimator.
ofFloat(this, "progress",
(float)this.getProgress(), progressTo);
animation.setDuration(duration);
animation.setStartDelay(delay);
animation.start();
}
}