【问题标题】:Kotlin Android extensions and retained fragmentKotlin Android 扩展和保留片段
【发布时间】:2015-09-20 03:46:56
【问题描述】:

我在我的项目中使用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) 并在每次此问题消失时重新创建片段。有什么想法可能导致这个问题吗?

【问题讨论】:

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


    【解决方案1】:

    UPD:问题现已修复。您不必再手动拨打clearFindViewByIdCache()。

    View 调用 onDestroyView() 后缓存不会被清除。有一个open issue。

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

    import kotlinx.android.synthetic.*
    

    【讨论】:

    • 问题现已修复。请参阅下面的@greenspand 答案
    【解决方案2】:

    只是为了澄清。现在问题已解决。您不必再通过 clearFindViewByIdCache() 了。请查看问题跟踪器:https://youtrack.jetbrains.com/oauth?state=%2Fissue%2FKT-8073

    【讨论】:

      【解决方案3】:

      我自己找到了答案。 Fragment 类不会直接膨胀布局——它有属性 view: View? 来保存它。这应该很明显,因为它是用onCreateView 创建的。为了访问view 中的属性,您必须设置导入

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

      然后按如下方式访问属性

      view?.text_view?.setText(text)
      

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

      【讨论】:

      • 如果我们在片段中使用 import kotlinx.android.synthetic.* 是否总是必须使用 clearFindViewByIdCache() ???
      • 根据another answer这个问题,你不应该再需要clearFindViewByIdCache()了。
      猜你喜欢
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多