2010-02-17 13 views
9

Ho problemi con l'impostazione di un nuovo Drawable sul mio ProgressBar.Come utilizzare setProgressDrawable() correttamente?

Se utilizzo setProgressDrawable() all'interno del metodo onCreate(), funziona perfettamente. Ma quando provo a chiamare lo stesso metodo all'interno di un callback post del gestore, non funziona e la barra di avanzamento scompare.

Qualcuno può spiegare questo comportamento? Come posso risolvere questo problema?

+0

Di solito, si modifica l'avanzamento tramite 'setProgress()'. Sostituire il mazzo "Drawable" è inusuale, ancora più strano farlo da un 'Handler' dopo che la barra è già stata renderizzata. Cosa stai cercando di ottenere qui? – CommonsWare

+0

Voglio cambiare il colore della barra dei programmi quando il valore ha raggiunto un determinato valore. – Martin

+1

Hai mai trovato la risposta? Attualmente ho lo stesso problema (oltre un anno dopo). Questo è solo un grosso insetto? – Peanut

risposta

1

urtato questo problema me stesso e sono riuscito a farlo funzionare :)

ho usato il AsyncTask per gestire lo sfondo attività/thread, ma l'idea dovrebbe essere la stessa di usare Runnable/Handler (anche se AsyncTask sembra più bello).

Quindi, questo è quello che ho fatto ... inserire setContentView(R.layout.my_screen); nel metodo onPostExecute! (. Vale a dire invece del metodo onCreate)

modo che il codice simile a questa:

public class MyScreen extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // setContentView(R.layout.my_screen); !!! Don't setContentView here... (see bottom) 

    new MySpecialTask().execute(); 
} 

private int somethingThatTakesALongTime() { 
    int result; 
    // blah blah blah 
    return result; 
} 

private void updateTheUiWithResult(int result) { 
    // Some code that changes the UI 
    // For exampe: 
    TextView myTextView = (TextView) findViewById(R.id.result_text); 
    myTextView.setText("Result is: " + result); 

    ProgressBar anyProgressBar = (ProgressBar) findViewById(R.id.custom_progressbar); 
    anyProgressBar.setProgressDrawable(res.getDrawable(R.drawable.progressbar_style)); 
    anyProgressBar.setMax(100); 
    anyProgressBar.setProgress(result);  
} 

private class MySpecialTask extends AsyncTask<String, Void, Integer> { 
    ProgressDialog mProgressDialog; 

    @Override 
    protected void onPreExecute() { 
     mProgressDialog = ProgressDialog.show(MyScreen.this, "", "Calculating...\nPlease wait...", true); 
    } 
    @Override 
    protected Integer doInBackground(String... strings) { 
     return somethingThatTakesALongTime(); 
    } 

    @Override 
    protected void onPostExecute(Integer result) { 
     mProgressDialog.dismiss(); 
     setContentView(R.layout.my_screen); // setContent view here... then it works... 
     updateTheUiWithResult(result); 
    } 
} 
} 

Per essere onesti, il motivo per cui è necessario chiamare in setContentViewonPostExecute non ho idea ... ma così facendo significa che è possibile impostare stili personalizzati per le barre di avanzamento (e non scompaiono su di voi!)

+2

Questo perché 'onPostExecute' viene eseguito nello stesso thread dell'interfaccia utente, mentre' doInBackground' viene eseguito in un thread in background, che non può disegnare direttamente in l'interfaccia utente http://developer.android.com/reference/android/os/AsyncTask.html – MartinodF

0

Forse si inserisce il codice in una discussione che non è thread principale. Se si desidera lavorare con l'interfaccia utente, è necessario farlo nel thread principale :)

+0

È in una discussione. Ma io uso Handler.post (new Runnable() in modo che l'operazione venga gestita dal thread dell'interfaccia utente. Funziona molto bene per aggiornare il valore progressbar. (Ma non per modificare il drawable) – Martin

+0

Solo la mia esperienza, se qualche vista in attività come le finestre di dialogo (magari ProgressBar uguali) vengono visualizzate una volta, non è più possibile modificarle Come: si crea una AlertDialog nel metodo onCreateDialog che non contiene un messaggio. Quindi, nel metodo onPrepareDialog, si imposta il messaggio - > il messaggio non verrà visualizzato. Sth like cache, come ricordo. –

12
downloadingBar.setProgress(0); 

Drawable progressDrawable = getResources().getDrawable(R.drawable.download_progressbar_pause_bg); 

progressDrawable.setBounds(downloadingBar.getProgressDrawable().getBounds()); 

downloadingBar.setProgressDrawable(progressDrawable); 

downloadingBar.setProgress(mCurrentPercent); 
  1. primo luogo si dovrebbe ripristinare i progressi a zero
  2. Impostare limiti il ​​progresso disegnabili metodo
  3. Impostare nuovi progressi drawable
  4. Impostare nuovi progressi
+0

Sembra funzionare! (Ho saltato la cosa dei limiti, perché il metodo non esiste nemmeno in 'ProgressBar').Questo hack è documentato ovunque? –

+0

getDrawable() è ora obsoleto API aggiornato >> Drawable progressDrawable = ContextCompat.getDrawable (contesto, R.Drawable. Download_progressbar_pause_bg); – wadali

+0

grazie, ho perso un po 'di tempo su questo http://i0.kym-cdn.com/entries/icons/original/000/000/554/facepalm.jpg – ThinkDeep

0

Sono stato anche affrontando lo stesso problema, ma nel mio caso è dovuto all'uso di Drawable.mutate() . Quando ho rimosso quel metodo ha iniziato a funzionare bene. Ho anche notato che questo problema esiste sotto api level-21 (lollipop).

Problemi correlati