8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ComposeをFragmentの上で動かすときちょっとハマったこと

Last updated at Posted at 2021-04-08

内容

ActivityFragmentContainerViewをおいて、 fragmentManager使って Fragmentを設置したとします。

Fragmentはというと

class MainFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setContent {
                ComposenavigationsampleTheme {
                    Surface(color = Color.Green) {
                        Text(text = "This is Compose on MainFragment")
                    }
                }
            }
        }
    }
}

一見うまくいきそうですが、実行するとこんなエラーが

java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from DecorView@ef08ca9[MainActivity]

調べてみると、Compose UIコンテンツを Fragmentや既存のViewレイアウトに組み込む場合は、 ComposeView を使用して、その setContent()メソッドを呼び出すのですが、 ComposeView

ViewTreeLifecycleOwnerにアタッチする必要があるようです。

なので具体的には ActivityonCreate()ViewTreeLifecycleOwner.set(window.decorView, this)を追加してあげる必要があります。

結果的に Activityはというと

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ViewTreeLifecycleOwner.set(window.decorView, this)

        if (savedInstanceState == null) {
            val fragmentManager = supportFragmentManager
            val fragmentTransaction = fragmentManager.beginTransaction()
            fragmentTransaction.replace(R.id.container, MainFragment())
            fragmentTransaction.commit()
        }
    }
}

これで、 MainActivityMainFragmentComposeViewというような感じでComposeでのUI構築ができるようになりました。

これを使えば既存のプロジェクトに画面ごとにCompose移行ができそうな感じがします。

追記2021/05/29

MainActivityComponentActivityを継承すれば ViewTreeLifecycleOwner.setする必要はないみたいです。
では、既存のプロジェクトでComposeをFragment1つずつに徐々に入れていきたいとき、そうすればいいんじゃ?と思ったのですが、いきなり大元のActivityを ComponentActivityを継承するものにしてしまうと supportFragmentManagerが使えなくなってしまってちょっときつそうです。

参考

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?