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.

  • Allarme scade prima di quanto previsto quando si utilizza setInexactRepeating
  • Come accedere all'archiviazione esterna con i plugin di file di cordova / file-system?
  • Android + Pair dispositivi tramite bluetooth programmaticamente
  • Il flag di Vector Drawables non funziona nella libreria di supporto 24+
  • Passare i dati della casella di controllo alla attività successiva
  • aplying onPostExecute su onClickListener
  • 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.

  • Convertire il stream di input in bitmap
  • Il button di azione galleggiante non è visibile durante lo scorrimento dopo l'aggiornamento di Google Support & Design Library
  • Android: scorrimento infinito - ListView e Cursore
  • Connessione internet diretta su Android Wear?
  • ruotare e ridimensionare la vista dell'image con un singolo dito in android
  • L'imbottitura interna di Spinner è più grande su Android 6.0.1
  • 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.