使用FragmentContainerView替换<fragment>标签

4
Android Studio 提供了替换 <fragment> 标签中的 Google Maps 片段。在应用程序中,我没有 Navigation,但可能会添加。我应该用 <FragmentContainerView> 替换 <fragment> 标签吗?

enter image description here

看了一下https://proandroiddev.com/android-fragments-fragmentcontainerview-292f393f9ccf,发现我们也可以用 <androidx.fragment.app.FragmentContainerView> 替换 <FrameLayout>。我们应该这样做吗?
3个回答

3

<FragmentContainerView... 旨在替代 <FrameLayout... 和 <Fragment...。请参考这个类似问题的答案,了解使用 <FragmentContainerView 的好处。(答案链接)


谢谢!看了一下https://developer.android.com/reference/androidx/fragment/app/FragmentContainerView,我明白我们应该替换活动中的<FrameLayout>,而不是片段中的。 - CoolMind

1
感谢SABANTO,我用<androidx.fragment.app.FragmentContainerView>替换了<fragment><FrameLayout>(只在活动中替换了<FrameLayout>)。它在debug版本中可以正常工作,但在release版本中会崩溃。
android.view.InflateException: Binary XML file line #16 in com.example:layout/fragment_show_map: Binary XML file line #16 in com.example:layout/fragment_show_map: Error inflating class androidx.fragment.app.FragmentContainerView
Caused by: android.view.InflateException: Binary XML file line #16 in com.example:layout/fragment_show_map: Error inflating class androidx.fragment.app.FragmentContainerView
Caused by: androidx.fragment.app.FragmentActivity$HostCallbacks: Unable to instantiate fragment com.google.android.gms.maps.SupportMapFragment: make sure class name exists
Caused by: java.lang.ClassNotFoundException: com.google.android.gms.maps.SupportMapFragment

查看使用androidx.fragment.app.FragmentContainerView时出现ClassNotFoundExceptionhttps://dev59.com/b1UL5IYBdhLWcg3waXcr#61365688,我发现我们应该在proguard-rules.pro中添加一行或两行,具体取决于您在XML文件中有什么:

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    ...

proguard-rules.pro:

#-------------------------------------------------
# JetPack Navigation
# This fixes: 
# Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment androidx.navigation.fragment.NavHostFragment: make sure class name exists
# Caused by: androidx.fragment.app.FragmentActivity$HostCallbacks: Unable to instantiate fragment com.google.android.gms.maps.SupportMapFragment: make sure class name exists
#-------------------------------------------------
-keepnames class androidx.navigation.fragment.NavHostFragment
-keepnames class com.google.android.gms.maps.SupportMapFragment

不要忘记在发布版本(当然,在调试版本中也一样)中测试您的应用程序。


1
这是我如何使用androidx.fragment.app.FragmentContainerView
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment_content_main"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:navGraph="@navigation/nav_graph" />
</LinearLayout>

Kotlin 代码
    private val navController by lazy {
        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main) as NavHostFragment
        navHostFragment.navController
    }

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        appBarConfiguration = AppBarConfiguration(navController.graph)
    }


当你只是切换而不改变代码时,由于Google Android Studio的默认示例代码使用了,它会给你一个错误,你必须添加以及定义变量navController,但我真的不明白为什么他们推荐这样做,如果它有那么大的不同,我发现使用的代码更简洁,并且完全正常运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接