I'm using BottomNavigationView in a fragment and want to show different fragments on tap of each option og that. I'm able to see BottomNavigationView but I'm unable to load any fragment. I'm using below code for that.
res/layout/fragment_main_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<fragment
android:id="#+id/nav_menu_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottom_navigation_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/main_menu_nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemBackground="#drawable/bottom_view_selector"
app:labelVisibilityMode="labeled"
app:layout_anchorGravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="#menu/bottom_nav_menu"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
res/navigation/main_menu_nav_graph.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"
android:id="#+id/main_menu_nav_graph"
app:startDestination="#id/navigation_main_tab_fragment">
<fragment
android:id="#+id/navigation_main_tab_fragment"
android:name="com.pkg.ui.main.MainTabFragment"
android:label="#string/app_name"/>
</navigation>
MainTabFragment.kt
binding.bottomNavigationView.setOnItemSelectedListener {
when (it.itemId) {
R.id.home -> {
findNavController().navigate(R.id.nav_menu_to_main_fragment)
}
R.id.wallet -> {
findNavController().navigate(R.id.nav_menu_to_main_fragment)
}
else -> {
null
}
}
true
}
res/navigation/nav_menu_graph.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"
android:id="#+id/nav_menu_graph"
app:startDestination="#id/nav_menu_to_main_fragment">
<fragment
android:id="#+id/nav_menu_to_main_fragment"
android:name="com.pkg.ui.main.MainFragment"
android:label="#string/app_name" />
</navigation>
It always shows blank without MainFragment or either it gets crashed. Can anyone please check once and highlight if I'm making any mistake? Thanks in advance.
I think you should try this MainTabFragment
(supportFragmentManager.findFragmentById(R.id.nav_menu_fragment) as NavHostFragment).navController.apply {
binding.bnvAppBottomNav.setupWithNavController(this)
addOnDestinationChangedListener { _, destination, _ ->
binding.bnvAppBottomNav.visibility = when (destination.id) {
R.id.Home,
R.id.Wallet,
R.id.Profile -> GONE
else -> VISIBLE
}
}
}
And also try this in res/layout/fragment_main_tab.xml
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_menu_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottom_navigation_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/main_menu_nav_graph" />
Hope this give you some hint
Related
I have two different layout for portrait:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
and landscape orientation:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/container_channel"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/container_messages"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/container_messages"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/container_channel"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I have androidx.navigation:navigation-fragment-ktx:2.4.1 and my app perfectly change fragment in portrait orientation.
I would like to click on the button in the first fragment and change the state in the second
I got something like this:
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
supportFragmentManager.beginTransaction()
.replace(R.id.container_channel, ChannelsFragment())
.replace(R.id.container_messages, MessagesFragment())
.commit()
} else {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment
navController = navHostFragment.navController
}
Is it possible to make different navigation using this library for different orientations?
Is it possible to manage navigation from first fragment in second one using navigation lib?
I simply want to use bottomNavigation with Navigation Component. I tried multiple ways but fragment not switching . Only BottomNavigation display's
I have a running sample that uses fragment instead of FragmentContainerView. But I don't know why it's too complex to use the latest techtiques
DashboardActivity
#AndroidEntryPoint
class DashboardActivity : PBActivity(R.layout.activity_dashboard) {
val binding: ActivityDashboardBinding by viewbind()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val appBarConfiguration: AppBarConfiguration = AppBarConfiguration.Builder(
R.id.rankingFragment, R.id.homeFragment, R.id.profileFragment
).build()
setSupportActionBar(binding.toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
/*val navView = findViewById<BottomNavigationView>(R.id.bottom_nav)
NavigationUI.setupWithNavController(navView,navController)*/
///binding.navigationBb.setupWithNavController(navController)
///binding.toolbar.setupWithNavController(navController,null)
//binding.navHostFragment.s
binding.toolbar.setupWithNavController(navController,appBarConfiguration)
///binding.bottomNav.setupWithNavController(navController)
NavigationUI.setupWithNavController(binding.bottomNav, navController)
///NavigationUI.setupWithNavController(binding.bottomNav,navController)
}
}
activity_dashboard.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.appcompat.widget.Toolbar>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
app:menu="#menu/dashboard_nav_menu"
android:background="?android:attr/windowBackground"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
nav_graph.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/nav_graph"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/homeFragment"
tools:layout="#layout/fragment_home"
android:name="uk.co.planetbeyond.game_show_app.presentation.ui.main.fragments.HomeFragment"
android:label="HomeFragment" />
<fragment
android:id="#+id/rankingFragment"
tools:layout="#layout/fragment_ranking"
android:name="uk.co.planetbeyond.game_show_app.presentation.ui.main.fragments.RankingFragment"
android:label="RankingFragment" />
<fragment
android:id="#+id/profileFragment"
tools:layout="#layout/fragment_profile"
android:name="uk.co.planetbeyond.game_show_app.presentation.ui.main.fragments.ProfileFragment"
android:label="ProfileFragment" />
</navigation>
dashboard_nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/rankingFragment"
android:icon="#drawable/rankings_button_selected"
android:title="Ranking" />
<item
android:id="#+id/homeFragment"
android:icon="#drawable/home_button_selected"
android:title="#string/title_home" />
<item
android:id="#+id/profileFragment"
android:icon="#drawable/profile_icon_selected"
android:title="Profile" />
</menu>
The problem is not in the navigation components, your code looks fine regarding it; but that your main layout has a 0 size:
You need to set the root layout to match parent:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
Side note: the fragments will draw behind the toolbar as it constraints to the parent top edge; The same for the bottom part.
To fix this constraint it to the toolbar:
In the FragmentContainerView Replace:
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
With:
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:layout_constraintBottom_toTopOf="#+id/bottom_nav"
Cant understanding why it's not working...
another analog project bnv working correctly...
in-app app:startDestination="#+id/navigate_hot" work correctly, but on click bnv items - nothing happens
mainActivity.XML
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bttm_nav"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/white"
android:elevation="4dp"
app:itemIconSize="35dp"
app:itemTextColor="#color/bnv_tab_item_foreground"
app:itemIconTint="#color/bnv_tab_item_foreground"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="#menu/bottom_nav_menu"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/bnv_navigation" />
MainActivity.kt
override fun onSupportNavigateUp(): Boolean {
return findNavController(this#ActivityMain,R. id.nav_host_fragment).navigateUp()
}
private fun setupNavigation() {
val navController = findNavController(this#ActivityMain, R.id.nav_host_fragment)
bttm_nav.setupWithNavController(navController)
}
bnv_navigation.XML
<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/nav_graph"
app:startDestination="#+id/navigate_hot">
<fragment
android:id="#+id/navigate_news"
android:name="com.example.fatsale.fragments.NewsFragment"
android:label="News"
tools:layout="#layout/fragment_news" />
<fragment
android:id="#+id/navigate_hot"
android:name="com.example.fatsale.fragments.HotFragment"
android:label="Collection"
tools:layout="#layout/fragment_hot" />
<fragment
android:id="#+id/navigate_profile"
android:name="com.example.fatsale.fragments.ProfileFragment"
android:label="Profile"
tools:layout="#layout/fragment_profile" />
</navigation>
tell this dunkey what need to do..
In your menu file for bottomnavigationview, each item id has to same as fragment id which is added in navigation graph xml file. Also in menu file, Each item has to give OrderInCategory for fragment position no in bottomnavigationview.
I have the following nav_graph 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"
app:startDestination="#id/users_fragment"
android:id="#+id/nav_graph">
<fragment
android:id="#+id/users_fragment"
android:name="com.package.UsersFragment"
tools:layout="#layout/users_fragment"
android:label="UsersFragment">
<action
android:id="#+id/action_users_fragment_to_profile_fragment"
app:destination="#id/profile_fragment"
app:popUpTo="#id/users_fragment"
app:popUpToInclusive="true"/>
</fragment>
<fragment
android:id="#+id/profile_fragment"
android:name="com.package.ProfileFragment"
android:label="ProfileFragment">
<argument
android:name="userId"
app:argType="string" />
</fragment>
</navigation>
The main activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.package.UsersViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:background="#color/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/app_bar_layout"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
To navigate to the details I call:
val action = UsersFragmentDirections
.actionUsersFragmentToProfileFragment(
userId = user.userId,
)
navController.navigate(action)
where UsersFragmentDirections is generated by the safe-args plugin.
The problem is that when I press back the master fragment is not shown: the activity is closed.
If in the action I use app:popUpToInclusive="false" then the back button does not work anymore.
What should I do to be able to go to the UsersFragment from the ProfileFragment when the user press back?
You're popping users fragment while moving to profile fragment. So when you press back, there is nothing in the backstack and hence activity finishes..
So, to fix this issue you have two options:
1) Manually re-open/navigate users fragment
Or
2) Remove these two lines
app:popUpTo="#id/users_fragment"
app:popUpToInclusive="true"
When I clicked on the button this thing is happening
navigation destination com.android.example.cameraxbasic:id/action_camera_to_gallery is unknown to this NavController
This is my code in fragment
container.findViewById<ImageButton>(R.id.photo_view_button).setOnClickListener {
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(
CameraFragmentDirections.actionCameraToGallery(outputDirectory.absolutePath))
}
This is a full error description
In my case , I am using HomeFragment Having FragmentOne and FragmentTwo in HomeFragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".HomeFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="729dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentOne"
android:name="com.example.FragmentOne"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentTwo"
android:name="com.example.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fragmentCarosuel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
my nav_main.xml file is like below:
<?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/mobile_navigation"
app:startDestination="#+id/nav_home">
<fragment
android:id="#+id/nav_home"
android:name="com.example.HomeFragment"
android:label="#string/menu_home"
tools:layout="#layout/fragment_home">
<action
android:id="#+id/action_main_to_fragment_three"
app:destination="#id/fragmentThree" />
</fragment>
<fragment
android:id="#+id/fragmentThree"
android:name="com.example.FragmentThree"
android:label="fragment_three"
tools:layout="#layout/fragment_three" >
</fragment>
</navigation>
Now, I am Navigating from FragmentTwo any click event etc.:
NOTE: Please make sure while selection of navigation destingation in navGraph. Here i am using two sub fragment (FragmentOne and FragmentTwo) but my base fragment is HomeFragment. so i have to make action from HomeFragment. If anyone create destination from FragmentOne it is not accesible from HomeFragment and NavController did not identify.
HomeFragmentDirections.ActionMainToFragmentThree nextAction = HomeFragmentDirections.actionMainToFragmentThree();
NavController navController = NavHostFragment.findNavController(this);
navController.navigate(nextAction);
Sorry for poor English. Thanks