10

プロジェクトでKotlin Android 拡張機能を使用していますが、理解できない動作に遭遇しました。このコードを使用して、フラグメントをアクティビティに保持します。

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

すべてが期待どおりに機能します – Hello world!text_view.setText()が表示されます。初回起動時の画面。ただし、画面を回転させると機能しません。null 可能ではなく、いくつかのビューを参照する必要があるため、これは奇妙です。フラグメントを削除してそのままにしておくと、この問題が消えるたびに再作成されます。この問題の原因は何ですか?text_view.setText()text_viewsetRetainInstance(true)

4

3 に答える 3

15

UPD:この問題は現在修正されています。clearFindViewByIdCache()もう手動で呼び出す必要はありません。

Viewを呼び出した後、キャッシュはクリアされませんonDestroyView()未解決の問題があります。

今のところ、キャッシュをクリアするためclearFindViewByIdCache()に inを明示的に呼び出すことができます。onDestroyView()このメソッドはsyntheticパッケージの一部であるため、インポートする必要があります

import kotlinx.android.synthetic.*
于 2015-07-03T15:14:04.557 に答える
7

明確にするために。この問題は修正されました。clearFindViewByIdCache() を渡す必要はなくなりました。課題トラッカーを参照してください: https://youtrack.jetbrains.com/oauth?state=%2Fissue%2FKT-8073

于 2015-10-15T14:05:37.160 に答える
6

私は自分で答えを見つけました。Fragmentクラスはレイアウトを直接インフレートしません。それを保持するプロパティがview: View?あります。で作成されているため、これは明らかなはずonCreateViewです。内のプロパティにアクセスするにはview、インポートを設定する必要があります

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

次に、次のようにプロパティにアクセスします

view?.text_view?.setText(text)

これらのプロパティは null 可能であることに注意してください。

于 2015-07-02T15:21:05.930 に答える