How to make RTL appBarConfiguration androidx.navigation? - android

I want make RTL appBarConfiguration. and this is my code for MainActivity. is there any way that help me to do this without use custom toolbar or make some custom things?
I search and found this is android document : [navigation-ui][1]
but I look for something simple like layout direction if something like this is it available
MainActivity class:
private lateinit var drawerLayout: DrawerLayout
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
drawerLayout = binding.drawerLayout
val navController = this.findNavController(R.id.navHostFragment)
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
navController.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, _: Bundle? ->
if (nd.id == nc.graph.startDestination) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
} else {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
}
NavigationUI.setupWithNavController(binding.navView, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navigationController = findNavController(R.id.navHostFragment)
return navigationController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
return super.onBackPressed()
}
}
}
and here activity_main.xml:
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
tools:openDrawer="start"
tools:context=".MainActivity">
<fragment
android:id="#+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation"/>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/drawer_menu"
app:headerLayout="#layout/fragment_cart"
/>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>```
[![now it's look like this:][2]][2]
I wanna hamberger menu place in right and that three icon place in left
[1]: https://developer.android.com/guide/navigation/navigation-ui#kotlin
[2]: https://i.stack.imgur.com/eOur8.png

I can fix it by adding this section in activity_main.xml and MainActivity.kt
activity_main.xml
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
tools:openDrawer="start"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark" />
<fragment
android:id="#+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_menu"
app:headerLayout="#layout/fragment_cart"
/>
</androidx.drawerlayout.widget.DrawerLayout>
</layout> ```
MainActivity.kt:
``` class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var toolbar: androidx.appcompat.widget.Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
drawerLayout = binding.drawerLayout
toolbar = binding.toolbar
setSupportActionBar(toolbar)
//supportActionBar?.setDisplayHomeAsUpEnabled(true)
//supportActionBar?.setDisplayShowHomeEnabled(true)
val navController = this.findNavController(R.id.navHostFragment)
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
navController.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, _: Bundle? ->
if (nd.id == nc.graph.startDestination) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
} else {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
}
}
NavigationUI.setupWithNavController(binding.navView, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navigationController = findNavController(R.id.navHostFragment)
return navigationController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
return super.onBackPressed()
}
}
} ```
I hope this help someone.

Related

How to set TopLevelDestination in AppBarConfiguration when build a graph programmatically using the Kotlin DSL

I build a graph programmatically using the Kotlin DSL.
fun NavGraphBuilder.addGraph(resources: Resources) {
navigation(
startDestination = NavigationGraphRoute.LoginFragment.buildFullPath(),
route = NavigationGraphRoute.NavGraph.buildFullPath()
) {
addDestinations(resources)
}
}
private fun NavGraphBuilder.addDestinations(resources: Resources) {
fragment<SignInFragment>(
route = NavigationGraphRoute.LoginFragment.buildFullPath()
) {
label = resources.getString(R.string.login_fragment_label)
}
fragment<HomeFragment>(
route = NavigationGraphRoute.HomeFragment.buildFullPath()
) {
label = resources.getString(R.string.home_label)
}
And in MainActiivty.kt
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setSupportActionBar(binding.toolbarMain)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.title = ""
val toggle =
ActionBarDrawerToggle(
this,
binding.drawerLayout,
binding.toolbarMain,
R.string.open,
R.string.close
)
binding.drawerLayout.addDrawerListener(toggle)
toggle.syncState()
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
navController.createGraph(
startDestination = NavigationGraphRoute.LoginFragment.buildFullPath()
) {
addAuthGraph(resources = resources)
}
appBarConfiguration = AppBarConfiguration(navController.graph, binding.drawerLayout)
NavigationUI.setupWithNavController(binding.toolbarMain, navController, appBarConfiguration)
}
}
and in activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/greys_white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.fragment.app.FragmentContainerView
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"
android:layout_marginTop="?attr/actionBarSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="#+id/toolbar_main"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Custom Navigation Drawer Start -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/navigation_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.drawerlayout.widget.DrawerLayout>
So the question is, how can I set the top-level destination for HomeFragment in AppBarConfiguration
Currently it setted like appBarConfiguration = AppBarConfiguration(navController.graph, binding.drawerLayout)
So, how can I set appBarConfiguration in such a way where I can set HomeFragment as TopLevelDestination. The reason why i needed as top is on the HomeFragment I need to see the Hamburger menu in toolbar and on another fragment it should show back. As I using Single Activity Architecture.

navigation componets: BottomNavigationView and navigationDrawer, In a project android

Good morning, any recommendations to use, navigation componets: BottomNavigationView and NavigationDrawer, In a project android.
This project was based on the Samples for Android Architecture Components repository. This is the repository where I took it out:
https://github.com/mackgaru/architecture-components-samples/tree/main/NavigationAdvancedSample
When clicking on a NavigationDrawer item, the navigation does not work well or the app crashes.
This is my repo, if you want to give me a hand:
https://github.com/mackgaru/nBottom_nDrawer.git
Thank you so much.
BottonNavigationView, NavigationDrawer
Here is the error
Process: com.cocktapp.cocktapp, PID: 27899
java.lang.IllegalArgumentException: Navigation action/destination com.cocktapp.cocktapp:id/action_navigation_home_to_homeDetalleFragment cannot be found from the current destination Destination(com.cocktapp.cocktapp:id/homeDetalleFragment) label=Detalle class=com.cocktapp.cocktapp.ui.home.HomeDetalleFragment
at androidx.navigation.NavController.navigate(NavController.java:938)
at androidx.navigation.NavController.navigate(NavController.java:875)
at androidx.navigation.NavController.navigate(NavController.java:861)
at androidx.navigation.NavController.navigate(NavController.java:849)
at com.cocktapp.cocktapp.ui.MainActivity.onNavigationItemSelected(MainActivity.kt:95)
at com.google.android.material.navigation.NavigationView$1.onMenuItemSelected(NavigationView.java:217)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:416)
at android.view.View.performClick(View.java:5646)
at android.view.View$PerformClick.run(View.java:22473)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6517)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
MainActivity
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private var currentNavController: LiveData<NavController>? = null
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
private lateinit var drawerLayout: DrawerLayout
private lateinit var viewModelHome: HomeViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
if (savedInstanceState == null) {
setupBottomNavigationBar()
}
setSupportActionBar(binding.includeMainContent.toolbarActivity)
drawerLayout = binding.drawerLayout
val navigationView: NavigationView = binding.navView
val toogle = ActionBarDrawerToggle(this, drawerLayout, binding.includeMainContent.toolbarActivity, R.string.open_navigation, R.string.close_navigation)
drawerLayout.addDrawerListener(toogle)
toogle.syncState()
navigationView.setNavigationItemSelectedListener(this)
}//fin onCreate
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
setupBottomNavigationBar()
}
private fun setupBottomNavigationBar() {
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
val navGraphIds = listOf(R.navigation.navigation_home, R.navigation.navigation_add, R.navigation.navigation_card, R.navigation.navigation_pay, R.navigation.navigation_config)
// Setup the bottom navigation view with a list of navigation graphs
val controller = bottomNavigationView.setupWithNavController(
navGraphIds = navGraphIds,
fragmentManager = supportFragmentManager,
containerId = R.id.nav_host_container,
intent = intent
)
// Whenever the selected controller changes, setup the action bar
controller.observe(this, Observer { navController ->
setupActionBarWithNavController(navController)
})
currentNavController = controller
Log.i("controller", "valor es = ${currentNavController!!.value}");
}
override fun onSupportNavigateUp(): Boolean {
Log.i("controller", "support = ${currentNavController?.value?.navigateUp()}");
val navController = findNavController(R.id.nav_host_container)
//return currentNavController?.value?.navigateUp() ?: false
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return super.onOptionsItemSelected(item)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.nav_camera){
Toast.makeText(this , "Camera Click", Toast.LENGTH_SHORT).show()
//Navigation.findNavController(this, R.id.navigationHome).navigate(R.id.action_navigation_home_to_homeDetalleFragment)
currentNavController?.value?.navigate(R.id.action_navigation_home_to_homeDetalleFragment)
drawerLayout.closeDrawer(Gravity.LEFT)
}
return true;
}
override fun onBackPressed() {
if(drawerLayout.isDrawerOpen(Gravity.LEFT)){
drawerLayout.closeDrawer(Gravity.LEFT)
}else{
super.onBackPressed()
}
}
}
activity_main.xml
<androidx.drawerlayout.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
android:id="#+id/include_main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/dra_main_content_appbar"/>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/dra_drawer_nav_header"
app:menu="#menu/drawer_navigation" />
</androidx.drawerlayout.widget.DrawerLayout>
dra_main_content_appbar
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".ui.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.Cocktapp.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar_activity"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/Theme.Cocktapp.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/dra_content" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
dra_content
<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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/dra_main_content_appbar">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_container"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
Each element of the BottonNavigationView has a different navigation file: example: navigation_home
<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/navigationHome"
app:startDestination="#id/navigation_home">
<fragment
android:id="#+id/navigation_home"
android:name="com.cocktapp.cocktapp.ui.home.HomeFragment"
android:label="Home"
tools:layout="#layout/fragment_home" >
<action
android:id="#+id/action_navigation_home_to_homeDetalleFragment"
app:destination="#id/homeDetalleFragment" />
</fragment>
<fragment
android:id="#+id/homeDetalleFragment"
android:name="com.cocktapp.cocktapp.ui.home.HomeDetalleFragment"
android:label="Detalle"
tools:layout="#layout/fragment_home_detalle" />
</navigation>
example: navigation_add
<?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/navigationAdd"
app:startDestination="#id/navigation_add">
<fragment
android:id="#+id/navigation_add"
android:name="com.cocktapp.cocktapp.ui.add.AddFragment"
android:label="Nuevo"
tools:layout="#layout/fragment_add" >
<action
android:id="#+id/action_navigation_add_to_addDetallekFragment"
app:destination="#id/addDetalleFragment" />
</fragment>
<fragment
android:id="#+id/addDetalleFragment"
android:name="com.cocktapp.cocktapp.ui.add.AddDetalleFragment"
android:label="Detalle"
tools:layout="#layout/fragment_add_detalle" />
</navigation>
All you have to do is:
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.nav_camera){
Toast.makeText(this , "Camera Click", Toast.LENGTH_SHORT).show()
if(currentNavController.currentDestination.id != R.id.homeDetalleFragment){
currentNavController?.value?.navigate(R.id.action_navigation_home_to_homeDetalleFragment)
}
drawerLayout.closeDrawer(Gravity.LEFT)
}
return true;
}

Android navigation onNavigationItemSelected not called

I have this DrawerLayout
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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/stock_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/stock_app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_stock_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/stock_nav_header"
app:menu="#menu/stock_activity_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
and then in the activity I have the following onCreate function:
class StockMainActivity: AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_stock_main)
val toolbar: Toolbar = findViewById(R.id.stock_toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.stock_drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_stock_view)
navView.bringToFront()
navView.setNavigationItemSelectedListener { item ->
if (item.itemId == R.id.nav_stock_home) {
finish()
}
true
}
val navController = findNavController(R.id.nav_stock_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_stock_home,
R.id.stock_navigation_fragment
), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_stock_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
But the navigation selected item listener is never called. It eventually navigates to the destination, but the listener is never called. I have checked similar posts, some suggesting to bring to the front the Navigation View, but to no avail. Please help ...
Ok, I have found the solution. I have put:
navView.bringToFront()
navView.setNavigationItemSelectedListener { item ->
if (item.itemId == R.id.nav_stock_home) {
finish()
}
true
}
At the end of onCreate... and it works now.

onNavigationItemSelected not calling when item is selected

I am adding footer-view in navigation drawer using following code -
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="#+id/nv_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|start">
<androidx.core.widget.NestedScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="#layout/nav_header_main"/>
<com.google.android.material.navigation.NavigationView
android:id="#+id/drawer_menu_body"
app:elevation="0dp"
android:layout_height="0dp"
android:layout_width="wrap_content"
android:layout_weight="1"
app:menu="#menu/activity_main_drawer">
</com.google.android.material.navigation.NavigationView>
<include layout="#layout/navigation_drawer_bottom_view"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
But now onNavigationItemSelected() is not calling also navigation drawer keeps open until we slide it manually. I am using navigation-component and nav graph.
This is my activity code -
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val navController = findNavController(R.id.nav_host_fragment)
drawer_menu_body.setNavigationItemSelectedListener(this)
nv_top.setNavigationItemSelectedListener(this)
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home,
R.id.nav_gallery,
R.id.nav_slideshow,
R.id.nav_tools,
R.id.nav_share,
R.id.nav_send
), drawer_layout)
setupActionBarWithNavController(navController, appBarConfiguration)
drawer_menu_body.setupWithNavController(navController)
nv_top.setupWithNavController(navController)
}
override fun onNavigationItemSelected(menu: MenuItem): Boolean {
Log.d("testing_navigation","testing_navigation")
drawer_layout.closeDrawer(GravityCompat.START)
return true
}
You attach setNavigationItemSelectedListener with NavigationView which will override during default configuration of setupWithNavController. So attach your listener after configuring default settings. Check below code.
nv_top.setupWithNavController(navController)
drawer_menu_body.setNavigationItemSelectedListener(this)
Update: To work with default navigation you have to handle like below:
override fun onNavigationItemSelected(menu: MenuItem): Boolean {
val handled = NavigationUI.onNavDestinationSelected(menu, navController)
if (!handled) {
// handle other navigation other than default
}
drawer_layout.closeDrawer(GravityCompat.START)
return handled
}
Dear this worked for me the item R.id.nav_logout i needed finish activity and not instance a fragment:
private lateinit var appBarConfiguration: AppBarConfiguration
var drawerLayout: DrawerLayout? = null
var navView: NavigationView? = null
var navController: NavController? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_customer_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
drawerLayout = findViewById(R.id.drawer_layout)
navView = findViewById(R.id.nav_view)
navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home, R.id.nav_service_requests), drawerLayout)
setupActionBarWithNavController(navController!!, appBarConfiguration)
navView!!.setupWithNavController(navController!!)
navView!!.setNavigationItemSelectedListener(this)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
menuItem.isChecked = true
drawerLayout!!.closeDrawers()
when (menuItem.itemId) {
R.id.nav_logout -> {
Prefs.putBoolean("flagLogin", false)
val intent = Intent(this#CustomerMainActivity, LoginActivity::class.java)
startActivity(intent)
finish()
return true
}
}
if( navController!!.currentDestination!!.id != menuItem.itemId)
navController!!.navigate(menuItem.itemId)
return true
}

Android No view found for id when using toolbar button

when i click to toolbar button, galleryFragment should open thats what i want to do. But i got these error:
java.lang.IllegalArgumentException: No view found for id 0x7f080051 (com.example.myapplication:id/container) for fragment GalleryFragment{e255e88 (923e67b6-0b21-4fac-acf1-f85b79a3311a) id=0x7f080051}
My button id is: shop
you can see my codes in onOptionsItemSelected function.
do you have any ideas about it?
this is my MainActivity:
package com.example.myapplication
class MainActivity : AppCompatActivity() {
var manager = supportFragmentManager
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
toolbar.setTitle("deneme")
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
R.id.nav_tools, R.id.nav_share, R.id.nav_send
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.shop -> {
var GalleryFragment = GalleryFragment()
var transaction = manager.beginTransaction()
transaction.add(R.id.container, GalleryFragment) //->
transaction.commit()
}
}
return super.onOptionsItemSelected(item)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
This is my main xml(include my button):
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/shop"
android:title="shop"
android:icon="#drawable/shop"
app:showAsAction="always">
</item>
</menu>
this is my mainactivity.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="#layout/toolbar">
</include>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
create a framelayout or any other view and set id as
android:id="#+id/container" in your activity_main.xml layout file
then issue will be fixed.
Reason : R.id.container id is not found in your activity_main.xml file
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Categories

Resources