2011-02-01 14 views
20

Ho un ListActivity che avvia un altro Activity in base alla selezione dell'elenco. Questo secondo Activity deve caricare un bel po 'di dati da Internet e, in quanto tale, si verifica un ritardo notevole tra quando l'utente fa clic su un elemento e quando viene visualizzato il numero Activity.Mostra una barra di avanzamento durante il caricamento di un'attività

Questo è un problema perché attualmente non ho modo di indicare all'utente che il suo clic è in fase di elaborazione (anche solo cambiando il colore della voce di elenco selezionata sarebbe sufficiente ma non riesco a trovare un buon modo di fare quella). Idealmente sarei in grado di visualizzare un numero indeterminato ProgressDialog mentre il secondo Activity si sta caricando.

Ho provato alcuni approcci diversi per questo, ma nulla sembra funzionare come desiderato.


ho provato la seguente:

  • il recupero dei dati serializzabili (non tutti, ma una certa parte) in un AsyncTask nel primo Activity e passando come un extra per il secondo. Questo non funzionava bene come ProgressDialog che ho creato in onPreExecute() non visualizzare immediatamente (sembra in ritardo di trattamento fatto in doInBackground() per qualche motivo.)

ecco il codice per questo:

AsyncTask<String, Void, String> read = new AsyncTask<String, Void, String>() { 
    Dialog progress; 

    @Override 
    protected void onPreExecute() { 
     progress = ProgressDialog.show(SearchActivity.this, 
       "Loading data", "Please wait..."); 
     super.onPreExecute(); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     DatasetReader reader = new DatasetReader(); 
     reader.setFundID(params[0]); 
     reader.addDatsets(FundProfile.datasets); 
     reader.populate(); 
     return reader.toString(); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     progress.dismiss(); 
    } 
}; 
read.execute(selectedItem.getUniqueID()); 
try { 
    action = new Intent(SearchActivity.this, FundProfile.class); 
    action.putExtra("data", read.get()); 
} catch(Exception ex) { 
    ex.printStackTrace(); 
} 
  • Nel metodo del secondo Activity onCreate() (questo non funziona affatto):

    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
    setProgressBarVisibility(true);

Ecco il metodo onCreate() per il secondo approccio:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.setTitleColor(Color.WHITE); 
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
    setProgressBarVisibility(true); 

    try { 
     setContentView(R.layout.fund_profile); 
     // init some data 
     setProgressBarVisibility(false); 
    } catch(Exception ex) { 
     FundProfile.this.finish(); 
    } 
} 
+1

Quali approcci diversi hai provato? Potresti condividere i tuoi tentativi? – Cristian

+0

Sono sorpreso che il primo approccio non abbia funzionato. Un 'ProgressDialog' mostrato in' onPreExecute() 'non dovrebbe essere trattenuto dal codice in' doInBackground() ', forse c'era qualche altro problema con il tuo codice? –

+0

Forse? Ho aggiunto il codice pertinente .. – Adam

risposta

16

Se si dispone di operazioni lunghe, non dovrebbero essere eseguite in onCreate in quanto ciò bloccherà l'interfaccia utente (indipendentemente dal fatto che l'attività venga visualizzata o meno). L'interfaccia utente impostata da onCreate non verrà visualizzata e l'interfaccia utente non risponderà fino al termine della chiamata onCreate.

Sembra che sia possibile avviare la seconda attività e visualizzare una barra di avanzamento (o requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);), quindi avviare un ASyncTask che sarà responsabile per l'aggiornamento dell'interfaccia utente una volta che i dati sono stati recuperati.

+0

Sì, ho capito che è il modo corretto per farlo (caricare i dati in un altro thread), ma volevo evitarlo per ora .. ma ho morso il proiettile e l'ho fatto in questo modo (AsyncTask lo rende meno doloroso di quanto avrebbe potuto essere ..) – Adam

2

Adam,

Sembra che si sta cercando la barra indeterminata di avanzamento: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.html

È possibile visualizzare questo mentre stai caricando il tuo secondo Activity quindi imposta la visibilità su false una volta che il secondo Activity ha caricato i suoi dati.

+0

L'ho provato, ma non sembra funzionare per me. – Adam

+0

Non lo vedi affatto? Che cosa esattamente non funziona? –

+0

La vista della prima attività rimane sullo schermo fino al completamento dell'intero metodo onCreate(), quindi non vedo mai una barra di avanzamento. – Adam

3

Spostare la creazione del intenti - e davvero tutto il necessario per fare dopo l'AsyncTask completa - in OnPostExecute:

@Override 
protected void onPostExecute(String result) { 
    super.onPostExecute(result); 
    progress.dismiss(); 
    Intent action = new Intent(SearchActivity.this, FundProfile.class); 
    action.putExtra("data", result); 
    // ... do more here 
} 

Il problema è che AsyncTask.get() blocks fino a quando l'operazione è completata.Quindi nel codice sopra, il thread dell'interfaccia utente è bloccato e ProgressDialog non viene mai data la possibilità di apparire fino al completamento dell'attività.

+0

Ah, questo spiega perché non ha funzionato .. – Adam

Problemi correlati