web-dev-qa-db-fra.com

android progressBar ne met pas à jour la vue de progression/dessinable

deux barres qui montre la progression d'une partie. Si l'utilisateur obtient des points ou si le temps est écoulé, etc. progressBars devrait être mis à jour:

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());
}

c'est à dire. Les sorties:

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

Le Log.d (...) à la fin afficheTOUJOURSles valeurs correctes, maisPARFOISles barres visuelles des progressBars n'indiquent pas les bons progrès. Ils montrent les progrès qui avaient été définis précédemment même si les getters de "max" et "progress" renvoient des valeurs correctes (dans l'exemple, la barre indique environ 20% (au lieu de 100%) pour le niveauBasque et environ 2% (au lieu de 40 %) pour le niveau Up-bar). Je n'arrive pas à comprendre pourquoi la sortie du journal est correcte mais les tirables sont fausses!? Le TextView (tv) est mis à jour correctement! Que se passe t-il ici? Comment puis-je résoudre ce problème?

20
Stuck

SOLUTION: C'est un bug dans ProgressBar!

enfin ... je pense avoir trouvé la solution ...

cela ne fonctionne pas comme on pourrait s'y attendre:

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

SetProgress (...) semble ne pas déclencher la mise à jour sur le dessin si la même valeur est passée à nouveau. Mais cela ne se produit pas non plus pendant le setMax. Donc, la mise à jour est manquante. On dirait un bug dans la barre de progression Android! Cela m'a pris environ 8 heures maintenant .. lol: D

Pour résoudre ce problème, je fais juste un bar.setProgress (0) avant chaque mise à jour ... ce n'est qu'une solution de contournement, mais cela fonctionne comme prévu:

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

J'ai pu faire en sorte que cela fonctionne avec View.post():

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

    // ...

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

Comme pour les réponses SKT, il est difficile de comprendre pourquoi cela devrait fonctionner alors que cela ne fonctionne pas.

mSeekBar.setProgress(percentOfFullVolume);

Cependant, cela semble être vrai jusqu’à Android Lollipop inclus.

18
david.mihola

Vous pouvez utiliser un gestionnaire pour mettre à jour progressbar

Handler progressBarHandler = new Handler();

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

progressBarHandler .post(new Runnable() {

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

Pour moi, appeler setMax() before setProgress() fonctionnait pour une raison quelconque.

8

Dans mon cas, je crée VerticalSeekBar, et la solution de Stuck ne fonctionne pas. Après des heures, j'ai trouvé une solution: 

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

J'espère que cela aidera n'importe qui.

7
nlt

Créer updateThumb (); méthode dans VerticalSeekbar

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

Et ensuite, appelez la méthode de mise à jour avec le pouce après avoir défini la progression.

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

son travail pour moi dans calss verticalseekbar

3
saravanan

Assurez-vous que style pour ProgressBar est défini sur Style = "@ Android: style/Widget.ProgressBar.Horizontal" Sinon, il indiquera une progression indéterminée.

(Juste au cas où cela aiderait quelqu'un)

2
Humayoun

J'ai essayé de nombreuses manières en appelant setProgress in Thread , runOnUiThread , Handler, Runnable . Tous ne travaillent pas.

Donc, finalement, définissez la valeur de dialog.setIndeterminate (false); marchera.

Une fois que vous avez défini dialog.setIndeterminate (true) ; la progression 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;
}
1
Tuan Nguyen

J'ai essayé toutes les solutions énumérées, elles ne fonctionnaient pas. Il s'avère que le vrai problème était que mon code était en cours d'exécution, bloquant essentiellement le thread d'interface utilisateur. Donc, la solution appropriée qui a résolu instantanément le problème était ... de placer mon code occupé dans une tâche asynchrone.

Dans mon cas, je chargeais plusieurs milliers d'enregistrements XML dans une base de données SQLite. Naturellement, je voulais mettre à jour la barre de progression. Le code qui aurait dû faire cela (prg_bar.setProgress (iProgressPercentage)) ne fait rien et à la fin de la charge, l'interface utilisateur a finalement eu la chance de s'exécuter. Poof, la barre de progression va de zéro à 100.

Le même code placé dans onProgressUpdate () de la tâche asynchrone, encapsulé autour du même code fonctionnel, fonctionnait parfaitement. Cela me rend très sceptique quant à l'idée "qu'il y a un bogue dans le code à barres de progression" et que régler le maximum et zéro ou n'importe lequel de ces facteurs était plus qu'un simple travail de contournement.

1
Anders8

Merci Stuck pour le post indiquant qu'il y a un bogue Android. J'ai aussi une barre de recherche verticale. 

Le problème était lorsque je changeais les progrès réalisables. Le dessinable serait mis à jour mais la barre serait mise à 0 et aurait une taille très petite. J'ai pu le redimensionner avec updateThumb (), mais l'avancement était toujours à 0.

Pour remettre la progression à la valeur d'origine, j'ai ajouté un mylayer.setLevel (...) ;. J'ai trouvé cela en lisant le code source de ProgressBar.doRefreshProgress (...). Vous pourriez peut-être faire 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

Ici, rien n’a fonctionné pour moi, alors j’ai proposé une solution un peu différente. J'ai remarqué que tout fonctionnait bien jusqu'à ce que j'essaie de modifier la valeur maximale (appelant setMax avec une valeur différente). 

Mon code:

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()
    }

}

Cela fonctionne parfaitement pour moi. Je peux appeler setMax comme d'habitude et il me suffit de remplacer getProgress et setProgress par getProgressFixed et setProgressFixed .

Ne substituez pas setProgress et getProgress . Ils s'appellent en interne.

Ma solution ne compte pas avec setMin . Si vous en avez besoin, changez le code en conséquence. 

0
Václav Hodek

tout le monde . si la progression existe et que la nouvelle valeur de progression est la même, la barre de progression n'est pas mise à jour .

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

    super.setProgress(progress);
}
0
egotron

Cela a fonctionné pour moi ... 

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

si vous aimez la barre de progression complète

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

si votre barre de progression est vide 

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