【问题标题】:How can i get a reference of a Fragment (SupportMapFragment) loaded by the NavHostFragment (of the Navigation Architecture components)如何获取由 NavHostFragment(导航架构组件)加载的片段(SupportMapFragment)的引用
【发布时间】:2018-10-30 14:26:00
【问题描述】:

我正在试用 google IO 2018 会议中介绍的导航架构组件。 我正在尝试制作一个包含三个选项卡的应用程序,每个选项卡一个片段。 在其中一个中,我想使用 Google Maps API 放置地图。 通常您应该在 Activity 的 OnCreate 中执行此操作

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

R.id.map isSupportMapFragmentmain_activity.xml内的id

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />

但是,导航架构组件设置略有不同。 main_activity.xml 仅包含一个 NavHostFragment(加载每个屏幕的片段)和一个 BottomNavigationView 以在应用程序的不同目的地之间移动。

<RelativeLayout android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<fragment
    android:id="@+id/my_nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:navGraph="@navigation/nav_graph"
    app:defaultNavHost="true"
    android:layout_height="match_parent"
    android:layout_width="match_parent" >

</fragment>


<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:itemBackground="@color/colorPrimary"
    app:itemIconTint="@android:color/white"
    android:layout_alignParentBottom="true"
    app:itemTextColor="@android:color/white"
    app:menu="@menu/bottom_navigation_main" />

</RelativeLayout>

我的导航图是这样的

<navigation 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"
app:startDestination="@id/map">

<fragment
    android:id="@+id/endFragment"
    android:name="douglas.leone.easytaxi.EndFragment"
    android:label="fragment_end"
    tools:layout="@layout/fragment_end" />

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" />

<fragment
    android:id="@+id/startFragment"
    android:name="douglas.leone.easytaxi.StartFragment"
    android:label="fragment_start"
    tools:layout="@layout/fragment_start" />

</navigation>

如您所见,第一个和第三个选项卡有两个片段 startFragmentendFragment。在第二个中有我试图引用的SupportMapFragment。 我不能使用标准的getSupportFragmentManager().findFragmentById(int id) 方式,因为main_activity.xml 只包含NavHostFragment

我尝试使用getChildFragmentManager() 进行试验,但没有取得多大成功。 我也尝试了navController.getCurrentDestination(),但它返回了一个NavDestination 对象,我无法使用它来检索加载的片段。

我找到的唯一解决方案是将SupportMapFragment 直接添加到activity_main.xml 中,使其与导航图完全分离,但这更像是一种解决方法而不是解决方案,因为我必须手动处理显示和隐藏地图当用户在另一个屏幕上时。

如果有人知道正确的解决方案,请分享。

【问题讨论】:

    标签: android android-fragments google-maps-android-api-2 android-jetpack android-architecture-navigation


    【解决方案1】:

    而不是将SupportMapFragment 直接添加到导航图中,您应该添加自己的片段类,该类将拥有和管理SupportMapFragment - 这将是调用getMapAsync 并在其中包含SupportMapFragment 的类自己的布局。

    Navigation 的目标是将 Activity 与各个目的地的内容分离。不推荐让 Activity 管理单个目的地。

    【讨论】:

    • 这是我尝试的第一件事,但我仍然无法引用它,因为getFragmentmanager().findFrgmentById() 无法找到它。我只能使用findViewById() 获得View 对象的引用
    • 我能够在 Fragment 的 onViewCreated 中直接找到调用 getChildFragmentManager().findFragmentById() 的解决方案
    • 是否可以在没有支持库的情况下使用地图片段,例如使用 AndroidX?
    • @BenoitDuffez - 如果您使用了 Refactor to AndroidX 选项,那么您应该能够将 SupportMapFragment 与 AndroidX 一起使用
    • 是的,但我不明白如何(我已经阅读了字节码交换)以及何时(编译时间?哪个编译器(java/kotlin)?一个 gradle 插件?在运行时?)。例如,我使我的地图片段按预期工作,但是有一个编译器警告说在childFragmentManager.findFragmentByIdSupportMapFragment 上的转换永远不会成功(编译器需要AndroidX),但它在运行时完全可以工作。这是预期的行为吗? (我的意思是 IDE 警告)
    猜你喜欢
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 2018-10-23
    相关资源
    最近更新 更多