如何在点击 FAB 时启动新的导航图?
How can I launch a new navigation graph, on FAB clicked?
问题:
我是 Android 的新人,我想我只是在概念上遇到了一些非常错误的事情。
我不能在同一个 activity 中有两个 navHostFragments。我收到此错误。
Error inflating class fragment
bottomNavigationView 图形本身工作得很好,我可以毫无问题地切换选项卡,当尝试在 FAB 单击上添加新导航时出现问题。 我不想用新的替换片段容器,我想启动一个全屏的新片段
上下文:
- 在 Main Activity 中,我有一个 可折叠工具栏、bottomNavigationView 和 FAB 按钮。我还想要两个 NavHostFragment,每个导航图一个。
- 第一个导航图 处理 bottomNavigationView 选项卡之间的切换(片段的内容显示在可折叠工具栏下方和 bottomNavigationView 顶部)
- 第二个导航图会出现在点击的FAB上,并且会全屏
我有:
这就是 activity_main.xml 的样子
<com.google.android.material.appbar.AppBarLayout
.....
/>
<fragment
android:id="@+id/waiterNavigationHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/waiter_navigation" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/appBarLayout"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment
android:id="@+id/bottomNavigationHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/bottom_navigation" />
</FrameLayout>
<FrameLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
.........
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
........
/>
</FrameLayout>
这是 waiter_navigation.xml,应该在 FAB 点击时全屏显示:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="@+id/waiter_screen">
<fragment
android:id="@+id/waiter_screen"
android:name=".app.ui.waiter.WaiterScreenFragment"
android:label="fragment_waiter"
tools:layout="@layout/fragment_waiter" >
<action
android:id="@+id/navigate_to_menu_screen"
app:destination="@id/menuScreenFragment" />
</fragment>
<fragment
android:id="@+id/menu_screen"
android:name=".app.ui.menu.MenuScreenFragment"
android:label="MenuScreenFragment"
tools:layout="@layout/fragment_menu" />
</navigation>
这是位于可折叠应用栏和 bottomNavigationView 之间的 bottom_navigation.xml:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="@+id/bottom_navigation"
app:startDestination="@id/home_screen">
<fragment
android:id="@+id/home_screen"
android:name=".app.ui.home.HomeScreenFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/navigate_to_receipt_screen"
app:destination="@id/receipt_screen"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
</fragment>
<fragment
android:id="@+id/receipt_screen"
android:name=".app.ui.receipt.ReceiptScreenFragment"
android:label="fragment_explore"
tools:layout="@layout/fragment_receipt" >
<action
android:id="@+id/navigate_to_profile_screen"
app:destination="@id/profile_screen"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
</fragment>
<fragment
android:id="@+id/profile_screen"
android:name=".app.ui.profile.ProfileScreenFragment"
android:label="fragment_more"
tools:layout="@layout/fragment_profile" />
</navigation>
完整的错误详细信息
2020-02-24 11:54:30.401 16857-16857/com.restaurant.app
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.restaurant.app, PID: 16857
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.restaurant.app/com.restaurant.app.ui.main.MainScreenActivity}:
android.view.InflateException: Binary XML file line #45: Binary XML
file line #45: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6806)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Caused by: android.view.InflateException: Binary XML file line #45: Binary XML file line #45: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #45: Error inflating class fragment
Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for
com.flypay.restaurant.app:id/waiter_screen
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:61)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28)
at androidx.navigation.NavController.navigate(NavController.java:933)
at androidx.navigation.NavController.onGraphCreated(NavController.java:577)
at androidx.navigation.NavController.setGraph(NavController.java:534)
at androidx.navigation.NavController.setGraph(NavController.java:499)
at androidx.navigation.NavController.setGraph(NavController.java:481)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:237)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:109)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:784)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:867)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:828)
at android.view.LayoutInflater.inflate(LayoutInflater.java:519)
at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.flypay.restaurant.app.ui.main.MainScreenActivity.onCreate(MainScreenActivity.kt:17)
at android.app.Activity.performCreate(Activity.java:7224)
at android.app.Activity.performCreate(Activity.java:7213)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
2020-02-24 11:54:30.402 16857-16857/com.restaurant.app
E/AndroidRuntime: at
android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6806)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@id/ADD_SCREEN_NAME"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/waiter_screen">
<fragment
android:id="@+id/waiter_screen"
android:name=".app.ui.waiter.WaiterScreenFragment"
android:label="fragment_waiter"
tools:layout="@layout/fragment_waiter" >
<action
android:id="@+id/navigate_to_menu_screen"
app:destination="@id/menuScreenFragment" />
</fragment>
<fragment
android:id="@+id/menu_screen"
android:name=".app.ui.menu.MenuScreenFragment"
android:label="MenuScreenFragment"
tools:layout="@layout/fragment_menu" />
</navigation>
问题:
我是 Android 的新人,我想我只是在概念上遇到了一些非常错误的事情。 我不能在同一个 activity 中有两个 navHostFragments。我收到此错误。
Error inflating class fragment
bottomNavigationView 图形本身工作得很好,我可以毫无问题地切换选项卡,当尝试在 FAB 单击上添加新导航时出现问题。 我不想用新的替换片段容器,我想启动一个全屏的新片段
上下文:
- 在 Main Activity 中,我有一个 可折叠工具栏、bottomNavigationView 和 FAB 按钮。我还想要两个 NavHostFragment,每个导航图一个。
- 第一个导航图 处理 bottomNavigationView 选项卡之间的切换(片段的内容显示在可折叠工具栏下方和 bottomNavigationView 顶部)
- 第二个导航图会出现在点击的FAB上,并且会全屏
我有:
这就是 activity_main.xml 的样子
<com.google.android.material.appbar.AppBarLayout
.....
/>
<fragment
android:id="@+id/waiterNavigationHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/waiter_navigation" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/appBarLayout"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment
android:id="@+id/bottomNavigationHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/bottom_navigation" />
</FrameLayout>
<FrameLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
.........
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
........
/>
</FrameLayout>
这是 waiter_navigation.xml,应该在 FAB 点击时全屏显示:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="@+id/waiter_screen">
<fragment
android:id="@+id/waiter_screen"
android:name=".app.ui.waiter.WaiterScreenFragment"
android:label="fragment_waiter"
tools:layout="@layout/fragment_waiter" >
<action
android:id="@+id/navigate_to_menu_screen"
app:destination="@id/menuScreenFragment" />
</fragment>
<fragment
android:id="@+id/menu_screen"
android:name=".app.ui.menu.MenuScreenFragment"
android:label="MenuScreenFragment"
tools:layout="@layout/fragment_menu" />
</navigation>
这是位于可折叠应用栏和 bottomNavigationView 之间的 bottom_navigation.xml:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="@+id/bottom_navigation"
app:startDestination="@id/home_screen">
<fragment
android:id="@+id/home_screen"
android:name=".app.ui.home.HomeScreenFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/navigate_to_receipt_screen"
app:destination="@id/receipt_screen"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
</fragment>
<fragment
android:id="@+id/receipt_screen"
android:name=".app.ui.receipt.ReceiptScreenFragment"
android:label="fragment_explore"
tools:layout="@layout/fragment_receipt" >
<action
android:id="@+id/navigate_to_profile_screen"
app:destination="@id/profile_screen"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"/>
</fragment>
<fragment
android:id="@+id/profile_screen"
android:name=".app.ui.profile.ProfileScreenFragment"
android:label="fragment_more"
tools:layout="@layout/fragment_profile" />
</navigation>
完整的错误详细信息
2020-02-24 11:54:30.401 16857-16857/com.restaurant.app E/AndroidRuntime: FATAL EXCEPTION: main Process: com.restaurant.app, PID: 16857 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.restaurant.app/com.restaurant.app.ui.main.MainScreenActivity}: android.view.InflateException: Binary XML file line #45: Binary XML file line #45: Error inflating class fragment at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6806) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) Caused by: android.view.InflateException: Binary XML file line #45: Binary XML file line #45: Error inflating class fragment Caused by: android.view.InflateException: Binary XML file line #45: Error inflating class fragment Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for com.flypay.restaurant.app:id/waiter_screen at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:61) at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28) at androidx.navigation.NavController.navigate(NavController.java:933) at androidx.navigation.NavController.onGraphCreated(NavController.java:577) at androidx.navigation.NavController.setGraph(NavController.java:534) at androidx.navigation.NavController.setGraph(NavController.java:499) at androidx.navigation.NavController.setGraph(NavController.java:481) at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:237) at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684) at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356) at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:109) at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135) at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356) at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:784) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734) at android.view.LayoutInflater.rInflate(LayoutInflater.java:867) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:828) at android.view.LayoutInflater.inflate(LayoutInflater.java:519) at android.view.LayoutInflater.inflate(LayoutInflater.java:427) at android.view.LayoutInflater.inflate(LayoutInflater.java:374) at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469) at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140) at com.flypay.restaurant.app.ui.main.MainScreenActivity.onCreate(MainScreenActivity.kt:17) at android.app.Activity.performCreate(Activity.java:7224) at android.app.Activity.performCreate(Activity.java:7213) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081) 2020-02-24 11:54:30.402 16857-16857/com.restaurant.app E/AndroidRuntime: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6806) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@id/ADD_SCREEN_NAME"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/waiter_screen">
<fragment
android:id="@+id/waiter_screen"
android:name=".app.ui.waiter.WaiterScreenFragment"
android:label="fragment_waiter"
tools:layout="@layout/fragment_waiter" >
<action
android:id="@+id/navigate_to_menu_screen"
app:destination="@id/menuScreenFragment" />
</fragment>
<fragment
android:id="@+id/menu_screen"
android:name=".app.ui.menu.MenuScreenFragment"
android:label="MenuScreenFragment"
tools:layout="@layout/fragment_menu" />
</navigation>