Kotlin Android扩展和保留片段

时间:2015-07-02 14:37:19

标签: android android-layout android-fragments kotlin kotlin-android-extensions

我在我的项目中使用Kotlin Android extensions,我遇到了一些我无法理解的行为。我使用此代码将我的片段保留在活动中:

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布局 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" />

一切都按预期工作 - text_view.setText()在首次启动时在屏幕上显示 Hello world!。但是当您旋转屏幕时,text_view.setText()不起作用。这很奇怪,因为text_view不可为空,必须对某些视图进行处理。如果删除setRetainInstance(true)并在每次此问题消失时重新创建片段。有什么想法会导致这个问题?

3 个答案:

答案 0 :(得分:15)

UPD:此问题现已解决。您不必再手动拨打clearFindViewByIdCache()

调用View后,

onDestroyView()缓存未清除。有open issue

现在,您可以在clearFindViewByIdCache()中显式调用onDestroyView()来清除缓存。此方法是synthetic包的一部分,因此您必须将其导入

import kotlinx.android.synthetic.*

答案 1 :(得分:7)

只是澄清一下。这个问题现在已经解决了。您不必再传递clearFindViewByIdCache()。请参阅问题跟踪器:https://youtrack.jetbrains.com/oauth?state=%2Fissue%2FKT-8073

答案 2 :(得分:5)

我自己找到了答案。 Fragment类不会直接扩充布局 - 它具有保存它的属性view: View?。这应该非常明显,因为它是使用onCreateView创建的。要访问view中的属性,您必须设置导入

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

然后按如下方式访问属性

view?.text_view?.setText(text)

请注意,这些属性可以为空。