Android Fragments 替换片段容器时不显示合成

wtlkbnrh  于 2023-01-31  发布在  Android
关注(0)|答案(1)|浏览(141)

我使用了一些片段处理FragmentContainerView活动,在该片段中,我希望在第一个片段中使用ComposeView与XML一起使用Compose,但当我尝试从第二个片段导航回第一个片段时,ComposeView中的组件消失了。
我已经使用replace策略设置了一个包含FragmentContainerView的片段,并像往常一样将片段放入列表中,但我不知道这种情况下会发生什么。
你可以在这个video中观看
这也是我的代码

导航活动.kt

import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri
import androidx.navigation.NavDeepLinkRequest
import androidx.navigation.Navigation
import androidx.navigation.findNavController
import id.derysudrajat.inlinebinding.viewBinding
import id.derysudrajat.library.R
import id.derysudrajat.library.databinding.ActivityNavigationBinding

class NavigationActivity : AppCompatActivity() {

    private val binding by viewBinding(ActivityNavigationBinding::inflate)

    private val listOfFragment = listOf(FragmentMainNav(), FragmentDetailNav())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        binding.btnHome.setOnClickListener{
            replace(HOME_NAV)
        }
        binding.btnDetail.setOnClickListener{
            replace(DETAIL_NAV)
        }
        Navigation.createNavigateOnClickListener(R.id.fragmentDetailNav, null)
    }

    private fun replace(nav: String) {
        supportFragmentManager
            .beginTransaction()
            .replace(
                binding.fragmentContainerView.id,
                if (nav == HOME_NAV) listOfFragment[0] else listOfFragment[1]
            )
            .commit()
    }

    companion object {
        const val HOME_NAV = "home_nav"
        const val DETAIL_NAV = "detail_nav"
    }
}

分段主导航kt

import android.os.Bundle
import android.view.View
import androidx.compose.material3.Text
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.lifecycle.Lifecycle
import androidx.navigation.findNavController
import id.derysudrajat.inlinebinding.BindingFragment
import id.derysudrajat.inlinebinding.viewBinding
import id.derysudrajat.library.R
import id.derysudrajat.library.databinding.FragmentNavMainBinding

class FragmentMainNav : BindingFragment<FragmentNavMainBinding>() {

    override val binding by viewBinding(FragmentNavMainBinding::inflate)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.textMain.text = "Fragment Main"

        binding.composeView.apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent { 
                Text(text = "This is Compose")
            }
        }

    }
}

片段导航主文件.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment Main"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_main" />

</androidx.constraintlayout.widget.ConstraintLayout>

分段详细信息导航kt

import android.os.Bundle
import android.view.View
import id.derysudrajat.inlinebinding.BindingFragment
import id.derysudrajat.inlinebinding.viewBinding
import id.derysudrajat.library.databinding.FragmentNavDetailBinding
import id.derysudrajat.library.databinding.FragmentNavMainBinding

class FragmentDetailNav : BindingFragment<FragmentNavDetailBinding>() {

    override val binding by viewBinding(FragmentNavDetailBinding::inflate)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.textDetail.text = "Detail Navigation"
    }
}

片段导航详细信息.kt

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_detail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Detail Navigation"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

我尝试使用不同的方法,如更改ViewCompositionStrategy,但仍然不起作用,我希望显示ComopseView,当片段被替换并返回时仍然显示,顺便说一句,我尝试的合成来自合成BOM 2022.10.00 - 2023.01.00,但当片段被替换时仍然消失。

oyt4ldly

oyt4ldly1#

我认为你可以把binding.composeView.apply {}块从onViewCreated移到onCreateView,如这里的官方文档中提供的示例所示。我已经使用compose bom 2023.01.00和普通的ViewBinding测试过了,它工作正常。所以HomeFragment应该是这样的:

class HomeFragment : Fragment() {

    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        val view = binding.root
        binding.composeView.apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                Text(text = "This is Compose")
            }
        }
        return view
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

作为补充说明,我不认为Navigation.createNavigateOnClickListener()是必要的,可以只是删除。

相关问题