9

Sto utilizzando Kotlin Android extensions nel mio progetto e ho trovato un comportamento che non riesco a capire. Io uso questo codice per mantenere il mio frammento nell'attività:Estensioni Kotlin Android e frammento trattenuto

val fragment = fragmentManager.findFragmentByTag("hello") ?: HelloFragment() 
fragmentManager.beginTransaction() 
       .replace(R.id.fragment_container, fragment, "hello") 
       .commit() 

Questa è la mantenuta Fragment:

import kotlinx.android.synthetic.hello.* 

public class HelloFragment : Fragment() { 
    val text = "Hello world!" 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super<Fragment>.onCreate(savedInstanceState) 
     setRetainInstance(true) 
    } 

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 
     return inflater?.inflate(R.layout.hello, container, false) 
    } 

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 
     super<Fragment>.onViewCreated(view, savedInstanceState) 

     text_view.setText(text) // <- does not work when retained 
    } 
} 

e il suo layout XML hello.xml:

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/text_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center" /> 

Tutto funziona come previsto: i display text_view.setText()Ciao mondo! sullo schermo al primo avvio. Ma quando si ruota lo schermo, lo text_view.setText() non funziona. Questo è strano perché text_view non è annullabile e deve refferare in qualche vista. Se si rimuove setRetainInstance(true) e si lascia il frammento ricreato ogni volta che questo problema scompare. Qualche idea su cosa potrebbe causare questo problema?

risposta

12

UPD: Il problema è stato risolto. Non è necessario chiamare manualmente clearFindViewByIdCache().

View cache non viene cancellata dopo aver chiamato onDestroyView(). C'è un open issue.

Per ora, è possibile invocare esplicitamente clearFindViewByIdCache() in onDestroyView() per cancellare la cache. Questo metodo è parte del pacchetto synthetic quindi bisogna importarlo

import kotlinx.android.synthetic.* 
+0

Grazie per la risposta, funziona. – Lamorak

+0

Il problema è stato risolto ora. vedere la risposta di @greenspand sotto – activedecay

4

Ho trovato la risposta da solo. La classe Fragment non gonfia direttamente il layout: ha la proprietà view: View? che la detiene. Questo dovrebbe essere abbastanza ovvio poiché è stato creato con onCreateView. Per poter accedere alle proprietà all'interno del view è necessario impostare l'importazione

import kotlinx.android.synthetic.hello.view.* 

e quindi accedere alla proprietà come segue

view?.text_view?.setText(text) 

Si noti che queste proprietà sono annullabili.

+0

Dobbiamo sempre usare clearFindViewByIdCache() se usiamo import kotlinx.android.synthetic. * Nei nostri frammenti ??? – cesards

+0

Non dovresti più aver bisogno di 'clearFindViewByIdCache()' secondo [un'altra risposta] (http://stackoverflow.com/a/33150682/4584675) a questa domanda. – Lamorak

+0

Sì, ho visto quella risposta in ritardo ;-) grazie amico! – cesards