android 如何从Compose内部添加现有片段

nwo49xxi  于 2023-10-14  发布在  Android
关注(0)|答案(4)|浏览(137)

我想打开一个现有的片段从撰写或如果我可以添加在同一撰写在全屏,这也将工作。以及如何从一个现有的片段导航到另一个现有的片段。

ws51t4hk

ws51t4hk1#

我们对在Compose中使用Fragments的建议记录在这里。
具体地说,您应该使用AndroidViewBinding composable来膨胀一个包含FragmentContainerView的XML,该FragmentContainerView承载您要在Compose中使用的片段。AndroidViewBinding具有特定于片段的处理,这就是为什么你想在AndroidView上使用它。请注意,您需要为此启用视图绑定。
XML文件示例:

<androidx.fragment.app.FragmentContainerView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/fragment_container_view"
  android:layout_height="match_parent"
  android:layout_width="match_parent"
  android:name="com.example.MyFragment" />

然后在Composable函数中:

@Composable
fun FragmentInComposeExample() {
    AndroidViewBinding(MyFragmentLayoutBinding::inflate) {
        val myFragment = fragmentContainerView.getFragment<MyFragment>()
        // ...
    }
}
yptwkmov

yptwkmov2#

我解决这个问题如下:

@Composable
fun ReusableFragmentComponent(
    someArgumentForFragment: FragmentArgument,
    fragmentManager: FragmentManager,
    modifier: Modifier = Modifier,
    tag: String = "ReusableFragmentTag"
) {
    AndroidView(
        modifier = modifier,
        factory = { context ->
            FrameLayout(context).apply {
                id = ViewCompat.generateViewId()
            }
        },
        update = {
            val fragmentAlreadyAdded = fragmentManager.findFragmentByTag(tag) != null

            if (!fragmentAlreadyAdded) {
                fragmentManager.commit {
                    add(it.id, ReusableFragment.newInstance(someArgumentForFragment), tag)
                }
            }
        }
    )
}

在我的例子中,我从一个片段(由导航组件托管)调用它,努力使我们的可重用片段compose兼容。我是这样做的:

class ReusableFragments : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        return ComposeView(requireContext()).apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                Column {
                    Text("ReusableFragment 1")
                    ReusableFragmentComponent(someArgument1, childFragmentManager, tag = "ReusableFragmentTag1")

                    Text("ReusableFragment 2")
                    ReusableFragmentComponent(someArgument2, childFragmentManager, tag = "ReusableFragmentTag2")
                }
            }
        }
    }

}

通过使标记可定制,可以将同一片段的多个不同示例添加到同一片段管理器。

3pmvbmvn

3pmvbmvn3#

这帮助了我:

@Composable
fun MyFragmentView(
    fragmentManager: FragmentManager,
    modifier: Modifier = Modifier
) {
    AndroidView(
        modifier = modifier.fillMaxSize(),
        factory = { context ->
            val containerId = R.id.container // some unique id
            val fragmentContainerView = FragmentContainerView(context).apply {
                id = containerId
            }

            val fragment = MyFragment()
            fragmentManager.beginTransaction()
                .replace(containerId, fragment, fragment.javaClass.simpleName)
                .commitAllowingStateLoss()

            fragmentContainerView
        }
    )
}

ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="container" type="id"/>
</resources>
lrl1mhuk

lrl1mhuk4#

文件

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.xxx" parent="Theme.MaterialComponents.DayNight.NoActionBar"/>
</resources>
  • 注意android:在你的AndroidManifest.xml活动中的主题
<activity android:name="com.xxx"
            android:exported="false"
            android:theme="@style/Theme.xxx"
            />
  • 将appcompat添加到您的build.gradle
implementation 'androidx.appcompat:appcompat:1.6.1'
  • 在撰写
AndroidView(factory = cb@{ context->
      val view = FragmentContainerView(context)
      view.id = ViewCompat.generateViewId()
      val selfId = view.id
      supportFragmentManager.commit {
          setReorderingAllowed(true)
          add<MyFragment>(selfId)
      }
      return@cb view
  }

相关问题