web-dev-qa-db-ja.com

android progressBarが進行状況ビュー/ドローアブルを更新しない

ゲームの進行状況を示す2つのバー。ユーザーがポイントやタイムアップなどを取得した場合、progressBarを更新する必要があります。

private TextView tv;
private ProgressBar levelHoldBar;
private ProgressBar levelUpBar;

//...
private void updateViews() {

    // ...
    levelHoldBar.setMax(currentLevel.getThreshold());
    levelHoldBar.setProgress(currentPoints > currentLevel.getThreshold() ? currentLevel.getThreshold() : currentPoints);

    levelUpBar.setMax(nextLevel.getThreshold());
    levelUpBar.setProgress(currentPoints > nextLevel.getThreshold() ? nextLevel.getThreshold() : currentPoints);

    tv.setText(currentPoints+"/"+currentLevel.getThreshold());

    Log.d(TAG, "hold prog/max "+levelHoldBar.getProgress()+"/"+levelHoldBar.getMax());
    Log.d(TAG, "up   prog/max "+levelUpBar.getProgress()+"/"+levelUpBar.getMax());
}

すなわち。出力:

12-03 17:48:33.918: DEBUG/MainActivity(6829): hold prog/max 20/20
12-03 17:48:33.918: DEBUG/MainActivity(6829): up   prog/max 20/50

最後のLog.d(...)は[〜#〜] always [〜#〜]正しい値を示していますが、[〜#〜]時々[〜#〜 ] progressBarsの視覚バーに正しい進行状況が表示されません。 「max」および「progress」のゲッターが正しい値を返す場合でも、以前に設定された進行状況を表示します(例では、バーはlevelHoldBarに対して約20%(100%ではなく)を示し、約2%(40ではなく)を示します。 %)levelUp-barの場合)。なぜログ出力は正しいのにドローアブルが間違っているのか理解できません!? TextView(テレビ)が正しく更新されます!何が起きてる?どうすれば修正できますか?

22
Stuck

[〜#〜] solution [〜#〜]:ProgressBarのバグです!

最後に...私は解決策を見つけたと思います...

これは期待どおりに機能しません。

bar.setMax(50);
bar.setProgress(20);
bar.setMax(20);
bar.setProgress(20);

同じ値が再度渡された場合、setProgress(...)はドローアブルの更新をトリガーしないようです。ただし、setMaxの間もトリガーされません。したがって、更新がありません。 Android ProgressBarのバグのようです!これには今から約8時間かかりました。笑:D

これを解決するには、各更新の前にbar.setProgress(0)を実行するだけです...これは回避策にすぎませんが、期待どおりに機能します。

bar.setMax(50);
bar.setProgress(20);
bar.setProgress(0); // <--
bar.setMax(20);
bar.setProgress(20);
45
Stuck

これをView.post()で動作させることができました:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // ...

    mSeekBar.post(new Runnable() {
        @Override
        public void run() {
            mSeekBar.setProgress(percentOfFullVolume);
        }
    });
}

SKTの回答と同様に、これが機能しないのになぜ機能するのかは不明です

mSeekBar.setProgress(percentOfFullVolume);

ただし、Android Lollipopを含む)までは正しいようです。

19
david.mihola

ハンドラーを使用してprogressbarを更新できます

Handler progressBarHandler = new Handler();

ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar1);;

progressBarHandler .post(new Runnable() {

      public void run() {
          bar.setProgress(progress);
      }
});
13
SKT

私にとって、setMax()beforesetProgress()の呼び出しは、何らかの理由で機能しました。

私の場合、VerticalSeekBarを作成しましたが、Stuckのソリューションが機能しません。数時間後、私は解決策を見つけました:

@Override
public synchronized void setProgress(int progress) {
    super.setProgress(progress);
    onSizeChanged(getWidth(), getHeight(), 0, 0);
}

誰かを助けることを願っています。

7
nlt

UpdateThumb();を作成します。 VerticalSeekbarのメソッド

public void updateThumb(){
     onSizeChanged(getWidth(), getHeight(), 0, 0);
}

そして、進行状況を設定した後、更新親指メソッドを呼び出します。

seekBar.setProgress((int) progress);
seekBar.updateThumb();

垂直シークバーカルスでの私の仕事

3
saravanan

setProgress in ThreadrunOnUiThreadHandler、Runnableを呼び出して、さまざまな方法で試しました。それらのすべてが動作しません。

したがって、最後にdialog.setIndeterminate(false);の設定値が機能します。

設定したらdialog.setIndeterminate(true);進行状況WONT UPDATE AT ALL

public static ProgressDialog createProgressDialog(Activity activity, int messageID, boolean cancelable) {
    ProgressDialog dialog = new ProgressDialog(activity, R.style.DialogButtonTint);
    dialog.setMessage(activity.getString(messageID));
    dialog.setIndeterminate(false);
    dialog.setMax(100);
    dialog.setSecondaryProgress(0);
    dialog.setProgress(0);
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    dialog.setCancelable(cancelable);
    dialog.show();
    return dialog;
}
3
Tuan Nguyen

ProgressBarのスタイルがstyle = "@ Android:style/Widget.ProgressBar.Horizo​​ntal"に設定されていることを確認してください。そうでない場合、不確定な進行状況が表示されます

(誰かを助けるために)

2
Humayoun

リストにあるすべての解決策を試しましたが、うまくいきませんでした。結局のところ、本当の問題は、コードが実行中にビジーで、本質的にUIスレッドをブロックしていたことです。したがって、問題を即座に修正した適切な解決策は...多忙なコードを非同期タスク内に置くことでした。

私の場合、XMLからSQLiteデータベースに数千のレコードをロードしていました。当然、プログレスバーを更新したかった。これを実行するはずだったコード(prg_bar.setProgress(iProgressPercentage))は何もせず、ロードの最後に、UIは最終的に実行する機会を得ました。プーフ、プログレスバーは0から100に変わります。

非同期タスクのonProgressUpdate()に配置された同じコードは、同じ機能コードをラップして完全に機能しました。これは、「進行状況バーコードにバグがある」という考えと、最大値とゼロを設定すること、またはそれらのいずれかが偶然の回避策以上のものであることに非常に懐疑的です。

1
Anders8

Androidバグがあることを述べた投稿をStuckに感謝します。垂直方向のシークバーもあります。

問題は、プログレッシブドローアブルを変更していたときでした。ドローアブルは更新されますが、バーは0に設定され、非常に小さいサイズになります。 updateThumb()でサイズを変更できましたが、進行状況はまだ0のままでした。

進行状況を元の値に戻すために、mylayer.setLevel(...);を追加しました。 ProgressBar.doRefreshProgress(...)のソースコードを読んでこれを見つけました。 seekBar.getProgressDrawable.setLevel(...)ができるかもしれません。

LayerDrawable mylayer = //new LayerDrawable()
seekBar.setProgressDrawable(mylayer);
seekBar.updateThumb();
seekBar.setProgress((int) chLevel);
mylayer.setLevel((int) (chLevel / MAX_LEVEL * 10000));
1
DanFredell

ここでは何もうまくいかなかったので、少し違う解決策を思いつきました。最大値を変更しようとするまで、すべてがうまく機能していることに気付きました(異なる値でsetMaxを呼び出す)。

私のコード:

class FixedSeekBar : SeekBar {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    companion object {
        private const val PROGRESS_MAX = 1000000.toDouble()
    }

    private var mLastMaxValue: Int = 100

    override fun setMax(max: Int) {
        mLastMaxValue = max
        super.setMax(PROGRESS_MAX.toInt())
    }

    fun setProgressFixed(progress: Int) {
        setProgress((PROGRESS_MAX / mLastMaxValue * progress).toInt())
    }

    fun getProgressFixed(): Int {
        return (getProgress() / PROGRESS_MAX * mLastMaxValue).toInt()
    }

}

これは私にとって完璧に機能します。通常どおりsetMaxを呼び出すことができ、getProgresssetProgressgetProgressFixedsetProgressFixed

setProgressおよびgetProgressをオーバーライドしないでください。それらは内部的に呼び出されます。

私のソリューションはsetMinでカウントされません。必要な場合は、それに応じてコードを変更してください。

0
Václav Hodek

全員。進行状況が存在し、新しい進行状況の値が同じ場合、進行状況バーは更新されません。新しい値を近い値として設定するのは簡単な方法です。

@Override
public synchronized void setProgress(int progress)
{
    if (getProgress() == progress)
    {
        if (progress > 0)   progress -= 1;
        else                progress += 1;
    }

    super.setProgress(progress);
}
0
egotron

これは私のために働いた...

OneFragmen.Java

public class OneFragment extends Fragment{

public OneFragment() {
    // Required empty public constructor
}
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;

int progress=0;
private Handler handler = new Handler();
TextView txtProgress;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(
    LayoutInflater inflater, 
    ViewGroup container,
    Bundle savedInstanceState ) {

   View view =  inflater.inflate(R.layout.fragment_one, container, false);
    getActivity().setTitle(R.string.app_name);

   final ProgressBar spinner = 
       (ProgressBar) view.findViewById(R.id.outerProgressBar);
    Resources res = getResources();
    Drawable drawable = res.getDrawable(R.drawable.circular);
    txtProgress = (TextView)view.findViewById(R.id.txtProgress);
    spinner.setProgressDrawable(drawable);
    spinner.setSecondaryProgress(100);
    spinner.setMax(100);
    spinner.setProgress(0);

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (progress < 100) {
                progress += 1;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        spinner.setProgress(progress);
                        txtProgress.setText(progress + "%");
                    }
                });
                try {
                    Thread.sleep(28);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
    return view;
  }
}
0
Mohammad Tahir

完全なプログレスバーが好きなら

time_prg_bar.setMax(100);
time_prg_bar.setProgress(0); <--

プログレスバーが空の場合

time_prg_bar.setMax(100);
time_prg_bar.setProgress(100); <--
0
Mr_Moradi