How to use android bottom sheet with android navigation component? - android

I based my code on this question : How to create BottomSheetDialogFragment using Navigation Architecture Component?
I want to use fragment bottom sheet with navigation component I used the following setup :
<fragment
android:id="#+id/mainFragment"
android:name="package.MainFragment"
android:label="main_fragment"
tools:layout="#layout/main_fragment" >
<action
android:id="#+id/action_mainFragment_to_bottomSheet"
app:destination="#id/bottomSheet" />
</fragment>
<dialog
android:id="#+id/bottomShee"
android:name="package.OptionFragment" />
and in the code
view.findNavController().navigate(R.id.action_mainFragment_to_bottomSheet)
But the problem is that the bottom sheet appears in another fragment and not shadowing current fragment.
is there any way to implement bottom sheet with android navigation component?

Your bottom sheet fragment needs to inherit from: BottomSheetDialogFragment() and not Fragment()

Related

Android Kotlin Navhost invisible problem?

When I add the View Host Fragment, the design becomes invisible in the xml section, what can I do?
While navigating in Android Studio, when I add nav host fragment to the xml part, the design side becomes invisible, what can I do?
If you encounter such a problem, do not forget to give tools to the xml side in the navigation section, and do not forget to set the constrait to the nav host.
Navigation xml into
xmlns:tools="http://schemas.android.com/tools"
For example
<fragment
android:id="#+id/firstfragment"
android:name="com.example.countryapps.firstfragment"
tools:layout="#layout/fragment_firstfragment"
android:label="firstfragment" >
<action
android:id="#+id/action_firstfragment_to_secondfragment"
app:destination="#id/secondfragment" />
</fragment>

NavigationController does not open new fragment if it is already associated with bottom navigation

I have a fragment in bottom navigation when try to launch new fragment with same id using navigation controller instead of launching new fragment it redirects me to bottom navigation tab.
here is my code
<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/home_navigation"
app:startDestination="#id/splashFragment">
<fragment
android:id="#+id/baseTabsFragment"
android:name="com.abc.abc.fragment.BaseTabsFragment"
android:label="BaseTabsFragment"
tools:layout="#layout/fragment_common_tabs">
<action
android:id="#+id/action_to_baseFragment"
app:destination="#id/baseTabsFragment"
app:launchSingleTop="false" />
</fragment>
</navigation>
And code to navigate.
findNavController().navigate(R.id.action_to_baseFragment)
Here is a link for more details on this
https://issuetracker.google.com/issues/262076827
Update: I want to avoid the code duplication. I will have same fragments with same actions but different id's looking for a better way to do it.
If i understand correctly, you want to navigate to the same fragment and fragment does not refresh.
If you use navigation component in visual interface you need to pull an arrow from your baseFragment onto baseFragment again, with this you will see an arrow like self pointed. If you don't use visual just paste below code and it will be created.
<action
android:id="#+id/action_to_BaseFragment"
app:destination="#id/baseTabsFragment"
app:popUpTo="#id/baseTabsFragment"
app:popUpToInclusive="true" />
We are using this way because if we want system to navigate, it needs different location then previous, as long as we using same fragment we need to pop the old one.
It happened due to bottom menu. In this case you need to call programmatically to click on that bottom button.
Replace
findNavController().navigate(R.id.action_to_baseFragment)
to
navController.navigate(
R.id.base_graph, null,
NavOptions.Builder().setPopUpTo(navController.graph.startDestinationId, true).build()
)

BottomNavigationView icons not highlighted with Navigation 2.4

I updated to Navigation 2.4 (def nav_version = "2.4") and now when tapping on a BottomNavigationView item it does not always highlight the icon or show the fragment the BottomNavigationView item id points to.
There are 3 bottom navigation tabs called Home, Actions, My Progress. From the Home fragment, you can navigate to SubFragment.
So the flow might be to start at Home --> go to SubFragment --> go to Actions with the BottomNavigationView --> and then tap on Home to go back. What this did before the update was open the Home fragment (desired behavior). Now when tapping on the Home icon it shows SubFragment and does not highlight the icon.
More details
This is the navController setup:
bottomNavigationView = findViewById(R.id.bottom_navigation_view)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
bottomNavigationView.setupWithNavController(navController)
The nav_graph structure is like this:
<fragment
android:id="#+id/home"
android:name="com.example.app.home"
android:label="Home"
tools:layout="#layout/home"
<action
android:id="#+id/action_home_fragment_to_sub_fragment"
app:destination="#id/sub_fragment"/>
</fragment>
<fragment
android:id="#+id/subfragment"
android:name="com.example.app.subfragment"
android:label="Sub Fragment"
tools:layout="#layout/subfragment" />
<fragment
android:id="#+id/actions"
android:name="com.example.app.actions"
android:label="Actions"
tools:layout="#layout/actions" />
<fragment
android:id="#+id/myprogress"
android:name="com.example.app.myprogress"
android:label="My Progress"
tools:layout="#layout/myprogress" />
The menu items id's for the BottomNavigationView are identical to nav_graph.
I thought the issue might be with the nav_graph structure not playing well with the new SDK, so I tried adjusting the structure of the nav_graph so that each navigation tab was within its own like this question answer has setup. It highlights the tab with this approach but still does not navigate to Home like the example above. Only to SubFragment.
Ideas on what I might be missing are appreciated!
Haven't figured out a fix for the issue yet, so downgraded to def nav_version = "2.3.5" and navigation works properly again.
This is the version before Navigation 2.4 as mentioned by # ianhanniballake above in comments.
I also came across with this issue. It is not a bug in the library.
Actually, when you link menu.xml with nav_graph.xml
You only specified only one fragmentId for each destination. Therefore, it is natural for icon not to change its current state when subfragment is selected.
Instead, you should use nested navigation graphs and use the id of that graph for menu.xml.
<navigation
android:id="#+id/home_destination"
app:startDestination="#id/home" >
<fragment
android:id="#+id/home"
android:name="com.example.app.home"
android:label="Home"
tools:layout="#layout/home"
<action
android:id="#+id/action_home_fragment_to_sub_fragment"
app:destination="#id/sub_fragment"/>
</fragment>
<fragment
android:id="#+id/subfragment"
android:name="com.example.app.subfragment"
android:label="Sub Fragment"
tools:layout="#layout/subfragment" />
</navigation>
<fragment
android:id="#+id/actions"
android:name="com.example.app.actions"
android:label="Actions"
tools:layout="#layout/actions" />
<fragment
android:id="#+id/myprogress"
android:name="com.example.app.myprogress"
android:label="My Progress"
tools:layout="#layout/myprogress" />
And when you are specifying the navigation_menu you will do like this:
<item
android:id="#+id/home_destination"
android:icon="#drawable/ic_read_quran"
android:title="#string/read_quran"
app:showAsAction="always" />

How to perform Bottom Navigation in Android using dynamic loaded modules with a second navigation graph

Im trying to use the navigation component with dynamic feature modules for an app that im currently working. Recently, i've configured the main navigation graph for loading the navigation between a welcome and a home screen.
When rendered the Home Screen (as defined in the main navigation graph), the fragments in the dynamic feature modules are dynamically loaded and displayed in the layout with the BottomNavigationView, but, as an included navigation graph, the destinations/actions inside the included navigation graphs are not executed nor recognized in the NavController in HomeFragment.
My question is:
How can I load successfully the dynamic feature modules navigation graph in the home screen, for ensuring the navigation flow for the included modules in the app when installed?
When saying "ensuring the navigation flow for the included modules" im refering to the fact that the included nav graphs and their destinations must work the same way as the normal navigation setup as when using a single nav graph.
For example, i selected Tab01 in the home screen bottom navigation, when shown, appears a list with information about news feed, then a click in a news item, it navigates to the news content fragment screen.
In this scenario, this error is shown:
java.lang.IllegalArgumentException: navigation destination action_news_list_to_detail is unknown to this NavController
at androidx.navigation.NavController.navigate(NavController.java:919)
at androidx.navigation.NavController.navigate(NavController.java:859)
at androidx.navigation.NavController.navigate(NavController.java:845)
at androidx.navigation.NavController.navigate(NavController.java:1093)
at org.example.dfm01.Tab01Fragment.handleSelectedItem(Tab01Fragment.kt:72)
at org.example.dfm01.Tab01Fragment.access$handleSelectedDestination(Tab01Fragment.kt:23)
at org.example.dfm01.Tab01Fragment$setupRecyclerView$$inlined$apply$lambda$1.invoke(Tab01Fragment.kt:58)
at org.example.dfm01.Tab01Fragment$setupRecyclerView$$inlined$apply$lambda$1.invoke(Tab01Fragment.kt:23)
at org.example.dfm01.Tab01recyclerAdapter$ViewHolder$bind$$inlined$apply$lambda$1.onClick(Tab01recyclerAdapter.kt:97)
at android.view.View.performClick(View.java:7155)
at android.view.View.performClickInternal(View.java:7124)
at android.view.View.access$3500(View.java:808)
at android.view.View$PerformClick.run(View.java:27370)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:359)
at android.app.ActivityThread.main(ActivityThread.java:7418)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
Im using the following dependencies for Navigation:
api "androidx.navigation:navigation-fragment-ktx:$nav_version"
api "androidx.navigation:navigation-ui-ktx:$nav_version"
api "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
Code notes the home screen / fragment:
Added a second navigation graph, that uses the <include-dynamic... /> tag for loading the dynamic feature modules.
[nav_graph_home.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">
<include-dynamic
android:id="#+id/included_nav_01"
app:graphPackage="org.example.dfm01"
app:graphResName="nav_tab_01"
app:moduleName="example_dfm_01" />
<include-dynamic
android:id="#+id/included_nav_02"
app:graphPackage="org.example.dfm02"
app:graphResName="nav_tab_02"
app:moduleName="example_dfm_02" />
<include-dynamic
android:id="#+id/included_nav_03"
app:graphPackage="org.example.dfm03"
app:graphResName="nav_tab_03"
app:moduleName="example_dfm_03" />
<include-dynamic
android:id="#+id/included_nav_04"
app:graphPackage="org.example.dfm04"
app:graphResName="nav_tab_04"
app:moduleName="example_dfm_04" />
</navigation>
Configured a menu xml file for the BottomNavigationView Widget in Home Fragment's layout, later, in the layout, i added the app:menu and the graph reference in the FragmentContainerView.
[fragment_home.xml]
<?xml version="1.0" encoding="UTF-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment_home"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph_home" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_home"
app:menu="#menu/menu_home_bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Inside the HomeFragment class, i made the setup for the navigation flow for BottomNavigationView, using the second navigation graph.
[HomeFragment.kt]
class HomeFragment : Fragment(fragment_home) {
private val viewBinding: FragmentHomeBinding by viewBinding()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val innerNavHostFragment =
childFragmentManager.findFragmentById(R.id.nav_host_fragment_home) as NavHostFragment
val innerNavController = innerNavHostFragment.navController
viewBinding.apply {
NavigationUI.setupWithNavController(bottomNavHome, innerNavController)
}
}
}
Answer i implemented is a little bit long and requires you to use NavigationExtensions from Google. You can check out this link for the answer. It also contains link to working sample in github.

Add Transition File in Navigation Graph of Android Application

I want to add an explode transition in my next fragment using the latest Navigation pattern "Navigation Graph".How to add a transition XML file(#transition/fade or #transition/slide or #transiton/explode) into Navigation Graph of android app.
You will probably want to define the desired transition in your navigation graph like this:
<fragment
// here your fragment is defined
<action
android:id="#+id/your_action_id"
app:destination="#id/yourDestinationFragment"
app:enterAnim="#anim/fade_in"
app:exitAnim="#anim/fade_out"
app:popEnterAnim="#anim/fade_in"
app:popExitAnim="#anim/fade_out" />
</fragment>
Note that you can define different animations for entering and leaving a fragment.
The animations you define will go into the /res/anim folder. You might have to create it if you don't find it.

Categories

Resources