9

Ich verwende Kotlin Android extensions in meinem Projekt und ich stieß auf etwas Verhalten, das ich nicht verstehen kann. Ich benutze diesen Code zu meinem Fragment in der Aktivität beibehalten:Kotlin Android Erweiterungen und beibehaltenes Fragment

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

Dies ist die Fragment beibehalten wird:

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 
    } 
} 

und seine XML-Layout 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" /> 

Alles funktioniert wie erwartet - die text_view.setText() zeigt Hallo Welt! auf dem Bildschirm beim ersten Start. Aber wenn Sie den Bildschirm drehen, funktioniert die text_view.setText() nicht. Das ist komisch, weil text_view nicht nullbar ist und auf irgendeine Ansicht verweisen muss. Wenn Sie setRetainInstance(true) entfernen und das Fragment jedes Mal neu erstellen lassen, wenn dieses Problem verschwindet. Irgendwelche Gedanken, was dieses Problem verursachen könnte?

Antwort

12

UPD: Das Problem ist jetzt behoben. Sie müssen clearFindViewByIdCache() nicht mehr manuell aufrufen.

View Cache wird nach dem Aufruf onDestroyView() nicht gelöscht. Es gibt eine open issue.

Für jetzt können Sie explizit clearFindViewByIdCache() in onDestroyView() aufrufen, um den Cache zu löschen. Dieses Verfahren ist ein Teil des synthetic Paket, so dass Sie importieren müssen, um es

import kotlinx.android.synthetic.* 
+0

Danke für die Antwort, es funktioniert. – Lamorak

+0

Das Problem ist jetzt behoben. Siehe Antwort von @greenspand unten – activedecay

4

Ich habe die Antwort selbst gefunden. Die Klasse bläht das Layout nicht direkt auf - es hat die Eigenschaft view: View?, die es enthält. Dies sollte ziemlich offensichtlich sein, da es mit onCreateView erstellt wird. Um die Eigenschaften für den Zugriff innerhalb der view Sie den Import zugreifen zu setzen haben

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

und dann die Eigenschaften wie

view?.text_view?.setText(text) 

Hinweis folgt, dass diese Eigenschaften auf NULL festlegbare sind.

+0

Müssen wir immer clearFindViewByIdCache() verwenden, wenn wir kotlinx.android.synthetic. * In unsere Fragmente importieren ??? – cesards

+0

Sie sollten 'clearFindViewByIdCache()' nicht mehr nach [einer anderen Antwort] (http://stackoverflow.com/a/33150682/4584675) auf diese Frage benötigen. – Lamorak

+0

Ja, ich sah diese Antwort spät ;-) Prost Kumpel! – cesards