2015-09-03 13 views
6

Ho un frammento che mostra un grafico a linee creato con MPAndroidChart. Il caricamento del frammento richiede circa 200 millisecondi.Esegui codice subito dopo che un frammento diventa visibile per la prima volta

Desidero migliorare le prestazioni dell'app percepita caricando i dati dei dati del grafico subito dopo che il frammento diventa visibile.

Pertanto, ho bisogno di eseguire il codice subito dopo che il frammento diventa visibile, ma solo la PRIMA volta che diventa visibile.

Non riesco a utilizzare onResume(), poiché viene chiamato appena prima che il frammento sia visibile.

Nota: non è possibile utilizzare un'attività asincrona, è necessario eseguirla sul thread dell'interfaccia utente. Non avrebbe comunque senso, dal momento che questa è un'inizializzazione di una volta che impiega circa 200 millisecondi.

+0

Stai dicendo che non puoi inserire il codice in Fragment's 'onResume' o Activity 'onResume'? – ChrisStillwell

+0

Attualmente il codice si trova in onCreateView() del frammento. Non posso comunque usare onResume(), né l'attività, né il frammento suResume(). – Mike76

+0

Non sono sicuro di capire il motivo per cui non puoi usare il frammento "onResume". Questo metodo viene chiamato dopo che il frammento diventa visibile. – ChrisStillwell

risposta

0

Inserirlo nel metodo onViewCreated().

+2

Sembra essere la cosa sbagliata. Viene chiamato anche prima di onResume(). -> ...... "Chiamato immediatamente dopo che onCreateView (LayoutInflater, ViewGroup, Bundle) è tornato, ma prima che qualsiasi stato salvato sia stato ripristinato nella vista, la gerarchia della vista del frammento non è tuttavia collegata al genitore a questo punto ". – Mike76

1

Fare qualcosa di molto lungo sul thread dell'interfaccia utente è una cattiva pratica: bloccherai l'intera interfaccia utente per la lunghezza dell'elaborazione (poiché c'è solo un thread dell'interfaccia utente). E 200ms è in realtà molto lungo, è 1/5 di secondo, facilmente rilevabile dall'occhio umano, immagina di giocare a un framerate di 5fps.

Percezione delle prestazioni significa non avere mai ritardi nell'interfaccia utente.

Utilizzare AsyncTask o AsyncTaskLoader per elaborare i dati, i callback verranno richiamati nel thread dell'interfaccia utente, quindi non preoccuparti. Puoi controllare se è una tantum o meno memorizzando i dati in, ad esempio, una variabile membro. Se è null - caricare, in caso contrario - utilizzare subito.

Se i dati sono abbastanza statici e non molto grandi, è necessario precaricarli prima che il frammento venga aperto (ad esempio, all'avvio di Attività o anche all'avvio dell'app) e passare semplicemente i dati al frammento quando si sta tentando (tramite un argomento Bundle).

+0

Non riesco a utilizzare AsyncTask poiché ho bisogno di inizializzare il mio grafico sul thread dell'interfaccia utente. 200 millisecondi sono lunghi, ma l'utente non può fare nulla senza questo grafico. Pertanto posso solo mostrare una barra di avanzamento per i 200 millisecondi. – Mike76

+0

la barra di avanzamento verrà bloccata se si prende 200ms del tempo di thread dell'interfaccia utente. Perché ne hai bisogno per essere elaborato sul thread dell'interfaccia utente? –

+0

Questo è vero, ma l'elaborazione si basa sull'aggiornamento dell'interfaccia utente del grafico. – Mike76

6
public class MyFragment extends Fragment{ 
    Boolean _areLecturesLoaded =false; 
    @Override 
    onCreateView(){ 
    //Inflate the required views. Code gets executed once View is made but not shown 
    return v; 
} 
@Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 
     //Code executes EVERY TIME user views the fragment 

     if (isVisibleToUser && !_areLecturesLoaded) { 
      _areLecturesLoaded = true; 
      // Code executes ONLY THE FIRST TIME fragment is viewed. 
     } 
    } 
} 

isVisisbleToUser è integrato ed è vero quando l'utente sta visualizzando il frammento corrente. Fino a quando l'utente non vedrà il frammento per la prima volta rimarrà falso. Se si desidera che il codice venga eseguito ogni volta che l'utente visualizza il frammento, posizionare il codice in quest'area ma al di fuori dell'istruzione if.

_areLecturesLoaded viene inizializzato come falsa e una volta che il frammento per la prima volta, è impostata su true garantire l'istruzione Se non sarà chiamato in futuro e il codice all'interno viene eseguito solo una volta

Tutti inizializzazione di punti di vista i pulsanti dei widget ecc. devono essere eseguiti in onCreate() per garantire che non vi siano possibilità di puntatore nullo e altre eccezioni fastidiose.

+0

Grazie ci proverò. – Mike76

+0

fammi sapere se hai problemi. Altrimenti accetta la risposta. Grazie –

+0

Purtroppo setUserVisibleHint non riceve mai una chiamata. L'ho provato con i log su Android 4.4. Forse funziona solo se userei un viewpager o qualcosa del genere. – Mike76

0

Può essere implementato utilizzando una variabile booleana statica. Ho usato il codice qui sotto per mostrare la finestra di avanzamento solo la prima volta che l'app viene lanciata.

public class SettingsFragment extends Fragment { 

    static boolean _areLecturesLoaded = true; 

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

     View rootView = inflater.inflate(R.layout.fragment_settings, container, false); 

     return rootView; 
    } 

    private class Getlimits extends AsyncTask<Void, Void, Void> { 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pd = ProgressDialog.show(getActivity(), "", "Loading...", true); 
      pd.setCancelable(false); 
     } 

     @Override 
     protected Void doInBackground(Void... arg0) { 
      //your background code 
      if(_areLecturesLoaded) { 
       try { 
        Thread.sleep(3500); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 

      return null; 
     } 
     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      // Dismiss the progress dialog 
      if (pd.isShowing()) 
       pd.dismiss(); 
      _areLecturesLoaded = false; 
     } 
    } 
} 
Problemi correlati