Котлин Android расширения и сохраненный фрагмент

я использую Котлин Android расширения в моем проекте, и я столкнулся с некоторым поведением, которое я не могу понять. Я использую этот код, чтобы сохранить свой фрагмент в activity:

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

это сохранить 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
    }
}

и его XML-макет Здравствуйте.в 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" />

все работает так, как ожидалось -text_view.setText() выводит Привет, мир! на экране при первом запуске. Но при повороте экран text_view.setText() не работает. Это странно, потому что text_view не nullable и должен reffer к некоторому представлению. Если убрать setRetainInstance(true) и оставить фрагмент заново каждый раз, когда эта проблема исчезает. Есть мысли, что может вызвать эту проблему?

3 ответов


UPD: проблема устранена. Вы не должны звонить clearFindViewByIdCache() больше вручную.

View кэш не очищается после вызова onDestroyView(). Есть открыть вопрос.

на данный момент Вы можете явно вызвать clearFindViewByIdCache() на onDestroyView() очистить кэш. Этот метод является частью synthetic пакет, поэтому вы должны импортировать его

import kotlinx.android.synthetic.*

просто для уточнения. Теперь проблема устранена. Вам не нужно проходить clearFindViewByIdCache () anylonger. См. раздел отслеживание проблем:https://youtrack.jetbrains.com/oauth?state=%2Fissue%2FKT-8073


Я сам нашел ответ. The Fragment класс не раздувает макет напрямую – он имеет свойство view: View?, которая держит его. Это должно быть довольно очевидно, так как он создан с onCreateView. Для доступа к свойствам в пределах view вы должны установить импортные

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

и затем получить доступ к свойствам следующим образом

view?.text_view?.setText(text)

обратите внимание, что эти свойства допускают.