Imansible trovare il filatore dopo aver ruotato lo schermo

Sto utilizzando Fragments per get un layout con due fragments quindi la mia class extends Fragments .

Sto caricando una listview sul fragment sinistra e sul fragment destro ho un'altra visualizzazione modificata. Qui, ho un spinner che devo cambiare il suo colore.

  • "Conversione a formato Dalvik non rioutput con errore 1" sul JAR esterno
  • Scaricamento / cache di Google Maps per l'utilizzo in modalità offline
  • Come get il token di accesso dopo che l'utente è connesso da Gmail in Android?
  • Android: come ScaleY basata su un'altra posizione dell'object?
  • Tasto Android Tooltip
  • Eseguire AsyncTask diverse volte
  • Ho questo codice:

     private void loadSpinner(int value) { //Not relevant code adapter = new ArrayAdapter<CharSequence>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_item, data); adapter.setDropDownViewResource(R.layout.spinner); spinner.setAdapter(adapter); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String value = parent.getItemAtPosition(position).toString(); ((TextView) parent.getChildAt(0)).setTextColor(getResources().getColor(R.color.black)); //Some code } 

    Il codice qui sopra funziona come previsto finchè ruotare lo schermo del mio dispositivo. Qui, ho ottenuto un nullpointerexception a ((TextView) parent.getChildAt(0)).setTextColor(getResources().getColor(R.color.black)); .

    Se commento la row sopra, poiché risparmiamo lo stato prima di ruotare lo schermo, dopo aver ruotato lo schermo, i miei dati vengono ripristinati e funzionano come previsto, tranne che il filatore che è in colore chiaro, quindi non visibile.

    Capisco che posso creare il mio layout di spinner e risolvere questo problema, ma vorrei sapere come posso risolvere questo problema.

  • Android: Forza i dati da submit via radio o WiFi
  • Come modificare il nuovo colore e l'altezza dell'indicatore TabLayout
  • Come modificare la dimensione del carattere di text selezionato in edittext a runtime?
  • android.content.res.Resources $ NotFoundException per ic_sync_black_24dp.xml
  • Android: Come posso get le coordinate xy all'interno di un'image / ImageView?
  • Autorizzazione per github.com su Android
  • One Solution collect form web for “Imansible trovare il filatore dopo aver ruotato lo schermo”

    Dopo la rotazione dello schermo, la tua vista Spinner non ha ancora viste per bambini (ancora potete verificare chiamando parent.getChildCount() ), quindi il tuo parent.getChildAt(0) restituisce null, con conseguente NPE .

    spiegazioni

    Dopo la creazione dell'attività, Android visualizza il suo contenuto chiamando onMeasure() seguito da onLayout() per each vista nella gerarchia del layout.

    Spinner avrà le sue viste per bambini create, popolate da dati da adattatore e allegate durante la chiamata a onLayout() , come si può vedere qui .

    Così, normalmente per il tuo Spinner avrai sequenza: onMeasure -> onLayout -> onItemSelected
    e da quando onLayout viene chiamato prima di onItemSelected – tutto funziona bene per l'avvio dell'attività iniziale.

    Adesso, dà un'occhiata a cosa succede quando ruoti lo schermo:

    Prima dell'attività viene distrutta la sua onSavedInstanceState viene chiamata che propaga la chiamata a Spinner 's onSavedInstanceState che salverà la posizione corrente selezionata.

    Dopo la rotazione, la tua attività viene ricreata e viene chiamata la sua onRestoreInstanceState .

    quando viene chiamata Activity # onRestoreInstanceState , alla fine verrà richiamata a onRestoreInstanceState di Spinner, che ha il seguente codice:

      SavedState ss = (SavedState) state; //...some code if (ss.selectedId >= 0) { mDataChanged = true; //...some more code } 

    Come potete vedere, imposterà sempre la bandiera mDataChanged se lo stato precedente del filatore è stato salvato con onSavedInstanceState .

    Quindi, viene chiamato onMeasure () , che ha il seguente codice:

      if (mDataChanged) { handleDataChanged(); } 

    L'implementazione di handleDataChanged () chiamerà eventualmente fireOnSelected (), triggersndo l' onItemSelected di Spinner.

    Così l' onItemSelected viene chiamato durante onMeasure , prima di onLayout .
    E come spiegato sopra, Spinner non ha figli prima che il suo onLayout sia chiamato.

    Spero che il problema sia chiaro ora.

    Soluzione

    Per confermare il comportmento e per risolvere il problema, è ansible fornire semplicemente l'implementazione vuota per onSavedInstanceState / onRestoreInstanceState nella tua attività (senza chiamata all'attuazione super):

     @Override protected void onSaveInstanceState(Bundle outState) { /* do nothing */ } 

    Ciò impedirebbe di impostare mDataChanged e onMeasure non fireOnSelected .

    Nota supplementare

    Non call attività super. l'implementazione quando l'override onSavedInstanceState / onRestoreInstanceState è sicuramente raccomandato, come minimo non sarà ansible salvare automaticamente gli stati delle proprie visualizzazioni interne (incluso il tuo spinner).
    Vi incoraggio a farlo solo per verificare il comportmento spiegato sopra e per vedere che NPE è andato.

    La soluzione preferibile è quella di definire TextView con il colore desiderato per l'elemento di filatura in un layout .xml e utilizzarlo per build ArrayAdapter per il filatore.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.