Iam using single activity navigation component structure.
In host activity iam using navigation drawer and bottom navigation.
So There are 2 frgaments inside bottom navigation Fragment A and Fragment B.
I need to add menu icons (search icon) for Fragment A and (chat icon) for Fragment B.
So how i can add these icons on Host Activity toolbar from fragment ?
HostActivity
private fun setupViews()
{
drawerLayout = binding.drawerLayout
// Finding the Navigation Controller
navController = findNavController(R.id.hostFragmentLanding)
// Setting Navigation Controller with the BottomNavigationView
binding.bottomNavView.setupWithNavController(navController)
appBarConfiguration = AppBarConfiguration(topLevelDestinationIds = TOP_LEVEL_DESTINATIONS, drawerLayout)
// Set up ActionBar
setSupportActionBar(binding.toolBar)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.navigationView.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
host_activity_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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title=""
app:theme="#style/ToolbarTheme"
>
<ImageView
android:id="#+id/logo"
android:layout_width="97dp"
android:layout_height="#dimen/dp_20"
android:src="#drawable/logo_sportsal"
android:layout_gravity="center"
/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="#+id/hostFragmentLanding"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:navGraph="#navigation/navigation_landing" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_behavior="#string/hide_bottom_view_on_scroll_behavior"
style="#style/Widget.MaterialComponents.BottomNavigationView"
app:menu="#menu/bottom_navigation_menu"
/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigation_view"
style="#style/Widget.MaterialComponents.NavigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start" />
</androidx.drawerlayout.widget.DrawerLayout>
I want to add menu (search)icon from Fragment A to the Hostactivity Toolbar
I have added menu icons directlty from the fragment class
Fragment A
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_home_fragment, menu)
menu.findItem(R.id.search).isVisible = false
menu.findItem(R.id.qrScan).isVisible = false
menu.findItem(R.id.notification).isVisible = true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.search) {
}
return super.onOptionsItemSelected(item)
}
So the menu items has been added to the Host Activities Toolbar automatically
I was having the same problem and this anwser solved my problem
I have overrided my onCreateOptionsMenu and onOptionsItemSelected functions in my fragment and the icon wasn't being shown in the toolbar. I only needed to add these lines to my onCreate method in my activity
setSupportActionBar(binding.activityMainToolbar);
getSupportActionBar()?.setDisplayShowTitleEnabled(false);
Related
Currently, I am using the Navigation component from Android and the actionbar title is displayed on the left. However, I kind of want it centralised to make things neater, is there any way to go about doing so?
Image of the actionbar title that is displayed on the left
Activity's code:
public class General extends AppCompatActivity {
private BottomNavigationView bottomNavigationView;
private NavController navController;
private AppBarConfiguration appBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.general);
bottomNavigationView = findViewById(R.id.bottomNavigationView);
navController = Navigation.findNavController(this, R.id.fragment);
appBarConfiguration = new AppBarConfiguration.Builder(R.id.addFragment, R.id.homeFragment).build();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}
}
Activity's XML Code
<?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=".General">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_navigation_menu">
</com.google.android.material.bottomnavigation.BottomNavigationView>
<fragment
android:id="#+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/the_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment XML Code:
<?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/the_navigation"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/homeFragment"
android:name="com.test.HomeFragment"
android:label="Home"
tools:layout="#layout/home_fragment" />
<fragment
android:id="#+id/addFragment"
android:name="com.test.AddFragment"
android:label="Add"
tools:layout="#layout/add_fragment" />
</navigation>
After a bit of searching, it seems like this did the trick. All I had to do was to add it to my Activity code.
As the fragments are a childs of Parent activity, so we can centralize or customize the title as we want on the Parent Activity.
Here is an example how to center the title without doing the iterate for all View widgets ...
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
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.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_settings, R.id.navigation_info
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
// Detect on where fragment we are, and custom the title from here
navController
.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, args: Bundle? ->
when(nd.id){
R.id.navigation_home -> {
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.title_home_action_bar_layout)
}
R.id.navigation_settings -> {
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.title_settings_action_bar_layout)
}
R.id.navigation_info -> {
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.title_info_action_bar_layout)
}
}
}
}
For the custom centered title : title_settings_action_bar_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/tvTitle"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Settings Baby Watcher"
android:textColor="#FFFFFF" />
</LinearLayout>
I added a NavigationView to my DrawerLayout. The problem is that it goes under the action and status bar. I would like it to be above preferably both bars, but I would be happy to get it at least over the action bar.
Even if the background color of the action bar is transparent it gets darker as the drawer is opened.
this is how my main activity looks like in 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#drawable/background"
android:fitsSystemWindows="true"
android:id="#+id/drawerLayout"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/sideMenu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#drawable/navigation_menu_background"
app:menu="#menu/navigation_menu"
/>
</androidx.drawerlayout.widget.DrawerLayout>
and here is the Kotlin code:
class MainActivity : AppCompatActivity() {
private var playlistFragment = PlaylistFragment.newInstance()
private var streamFragment = StreamFragment.newInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
replaceFragment(playlistFragment)
sideMenu.setNavigationItemSelectedListener { item ->
handleNavigationItemTap(item)
true
}
}
private fun replaceFragment(fragment:Fragment){
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragmentContainer, fragment)
fragmentTransaction.commit()
}
private fun handleNavigationItemTap(item: MenuItem){
when(item.itemId){
R.id.playlistFragmentItem -> replaceFragment(playlistFragment)
R.id.singleStreamItem -> replaceFragment(streamFragment)
}
drawerLayout.closeDrawer(GravityCompat.START)
}
}
I'm using SDK 28 and android X element.
I'm trying imitate Instagram's UI
I had already try to combine two deafult navigation from Android Studio template.
And it has some coulples bug that I can't fix.
I'm coding Navigation on MainActivity.kt
Take example like :
1.Missing the Humbuger Icon at Fragment what launch by Bottom Navigation
2.Drawer Navigation Didn't Cover Navigation
Code
Main Activity
package com.odstudio.ourdiet
import android.os.Bundle
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import com.google.android.material.bottomnavigation.BottomNavigationView
class MainActivity : AppCompatActivity() {
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)
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_gallery, R.id.nav_slideshow, R.id.nav_tools, R.id.nav_share, R.id.nav_send
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
val bottomNavView: BottomNavigationView = findViewById(R.id.navigation)
bottomNavView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
// 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 onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private val mOnNavigationItemSelectedListener =
BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
findNavController(R.id.nav_host_fragment).navigate(R.id.nav_home)
}
R.id.navigation_groups -> {
findNavController(R.id.nav_host_fragment).navigate(R.id.nav_groups)
}
R.id.navigation_friends -> {
findNavController(R.id.nav_host_fragment).navigate(R.id.nav_friends)
}
}
false
}
}
Layout
Activity_main.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"
android:fitsSystemWindows="true">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:elevation="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/activity_main_bottom" />
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="-200dp"
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/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>
</androidx.constraintlayout.widget.ConstraintLayout>
app_bar_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_main.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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main">
<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:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Image
Home Page WithoutHumbuger Icon
Drawer Navigation Didn't Cover Navigation
OK, this one was pretty straight forward. I took the default nav drawer project and added a few changes.
First, wrap the DrawerLayout and your added BottomNavigation in a ConstraintLayout.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true">
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
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/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>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:elevation="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Then in MainActivy add the OnNavigationSelectedListener and set it in onCreate()
MainActivity.kt
class MainActivity : AppCompatActivity() {
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)
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)
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
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 onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
// Set up navigation here
when (item.itemId) {
R.id.navigation_rivers -> findNavController(R.id.nav_host_fragment).navigate(R.id.nav_river)
} R.id.navigation_favorites -> findNavController(R.id.nav_host_fragment).navigate(R.id.nav_favs)
R.id.navigation_map -> findNavController(R.id.nav_host_fragment).navigate(R.id.nav_map)
}
false
}
And make sure you have your bottom nav menu setup.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_rivers"
android:icon="#drawable/ic_sea"
android:title="#string/title_rivers"/>
<item
android:id="#+id/navigation_favorites"
android:icon="#drawable/ic_heart"
android:title="#string/title_favorites"/>
<item
android:id="#+id/navigation_map"
android:icon="#drawable/ic_location"
android:title="#string/title_map"/>
</menu>
UPDATE:
I updated MainActivity.kt above.
Here is my nav graph mobile_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/mobile_navigation"
app:startDestination="#+id/nav_home">
<!-- Other Drawer Fragments here, removed for brevity -->
<fragment
android:id="#+id/nav_share"
android:name="com.stackoverflowdualnav.ui.share.ShareFragment"
android:label="#string/menu_share"
tools:layout="#layout/fragment_share" />
<fragment
android:id="#+id/nav_send"
android:name="com.stackoverflowdualnav.ui.send.SendFragment"
android:label="#string/menu_send"
tools:layout="#layout/fragment_send" />
<!-- Bottom Nav Below -->
<fragment
android:id="#+id/nav_river"
android:name="com.stackoverflowdualnav.ui.send.RiverFragment"
android:label="#string/menu_river"
tools:layout="#layout/fragment_river" />
<fragment
android:id="#+id/nav_favs"
android:name="com.stackoverflowdualnav.ui.send.FavoritesFragment"
android:label="#string/menu_favorites"
tools:layout="#layout/fragment_map" />
<fragment
android:id="#+id/nav_map"
android:name="com.stackoverflowdualnav.ui.send.NavMapFragment"
android:label="#string/menu_map"
tools:layout="#layout/fragment_map" />
This works as-is, just adapt it to your use case.
I have an app that I am using with androidx components and I cannot get it to show the hamburger icon indicating a DrawerActivity. Here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer_layout"
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_main"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
style="#style/Widget.MyApp.ActionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/Base.ThemeOverlay.AppCompat.Dark"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/sliding_tabs"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<com.webnation.begonerobotexters.widgets.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:layout_constraintBottom_toTopOf="#+id/viewpager"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/sliding_tabs"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- The navigation drawer -->
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="#android:color/white"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/menu_drawer"/>
</androidx.drawerlayout.widget.DrawerLayout>
Here is how I am setting up navigation drawer in the activity:
private fun setUpNavigationDrawer() {
setSupportActionBar(toolbar)
val actionBar = supportActionBar
try {
assert(actionBar != null)
actionBar?.setDisplayHomeAsUpEnabled(true)
actionBar?.setHomeButtonEnabled(true)
//actionBar?.setSubtitle(getString(R.string.subtitle))
actionBar?.setDisplayShowTitleEnabled(true)
} catch (ignored: Exception) {
Timber.e(ignored)
ignored.printStackTrace()
}
toolbar?.setBackgroundColor(ContextCompat.getColor(this, R.color.colorPrimary))
toolbar?.setTitleTextColor(ContextCompat.getColor(this, R.color.tab_text_color))
navigation_view.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true
when (menuItem.itemId) {
R.id.navigation_item_1 -> {
val intent = Intent(this, EulaActivity::class.java)
intent.putExtra(keyFileName, "privacy")
startActivity(intent)
}
R.id.navigation_item_2 -> {
val intent = Intent(this, EulaActivity::class.java)
intent.putExtra(keyFileName, "eula")
startActivity(intent)
}
R.id.navigation_item_3 -> {
}
}
if (navigation_view != null) {
drawer_layout?.closeDrawer(navigation_view)
}
true
}
mDrawerToggle = object: ActionBarDrawerToggle(this, drawer_layout, toolbar,R.string.drawer_open, R.string.drawer_close) {
override fun onDrawerOpened(drawerView: View) {
super.onDrawerOpened(drawerView)
invalidateOptionsMenu()
}
override fun onDrawerClosed(view: View) {
super.onDrawerClosed(view)
//getSupportActionBar().setTitle(mActivityTitle);
invalidateOptionsMenu()
}
}
mDrawerToggle.isDrawerIndicatorEnabled = true
drawer_layout?.addDrawerListener(mDrawerToggle)
mDrawerToggle.syncState()
}
Here is my DrawActivity:
class DrawerActivity : AppCompatActivity() {
lateinit var draw_layout: DrawerLayout
lateinit var mDrawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onStart() {
super.onStart()
draw_layout = findViewById<DrawerLayout>(R.id.drawer_layout)
mDrawerToggle = ActionBarDrawerToggle(this, draw_layout, 0, 0)
draw_layout.addDrawerListener(mDrawerToggle)
val actionBar = supportActionBar
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setDisplayShowHomeEnabled(true)
actionBar.setDisplayShowTitleEnabled(true)
actionBar.setDisplayUseLogoEnabled(false)
actionBar.setHomeButtonEnabled(true)
}
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
mDrawerToggle.syncState()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return mDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
}
}
What am I doing wrong?
ActionBarDrawerToggle is deprecated for quite a while; one can use the framework's own resId for that button (to be inflated into the ActionBar's custom view - so that it will appear where it should):
<androidx.appcompat.widget.AppCompatImageButton
android:id="#android:id/home"
android:src="#drawable/ic_menu_black_36dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#null" />
The one can get the click event along with top-right menu events; for example:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
/* hide/show NavigationView */
break;
...
}
}
I found out my viewpager/sliding bar tab was covering the action bar. So I switched out my ConstraintLayout for a LinearLayout, and poof it appeared.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:orientation="vertical"
tools:showIn="#layout/activity_main"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
style="#style/Widget.MyApp.ActionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/Base.ThemeOverlay.AppCompat.Dark"
/>
<com.webnation.begonerobotexters.widgets.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
/>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
</LinearLayout>
<!-- The navigation drawer -->
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="#android:color/white"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/menu_drawer"/>
</androidx.drawerlayout.widget.DrawerLayout>
I am trying to learn how to use the navigation controller. and the problem is, My app seems not responding, it takes a very long time to show the main activity, and I can't also press the back button (seems not active)
here is the screenshot of my navigation graph, I am trying to set the host fragment in my Main Activity, as you can see, it seems a little bit weird that the bottom navigation view and the toolbar seem double on the NavHostFragment.
here is the screenshot of my main activity:
here is my mainActivity xml:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="?attr/actionBarTheme"
android:minHeight="?attr/actionBarSize"
android:id="#+id/toolbar"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<fragment
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/nav_host_fragment"
app:layout_constraintBottom_toTopOf="#+id/bottom_nav"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/navigation_graph"
app:defaultNavHost="true"
/>
<android.support.design.widget.BottomNavigationView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#color/colorPrimary"
app:itemIconTint="#color/color_bottom_view_navigation"
app:itemTextColor="#color/color_bottom_view_navigation"
app:menu="#menu/menu_bottom_view"
app:labelVisibilityMode="labeled"
android:id="#+id/bottom_nav"/>
</android.support.constraint.ConstraintLayout>
and here is the xml of navigation graph:
<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/navigation_graph"
app:startDestination="#id/mainActivity">
<activity android:id="#+id/mainActivity" android:name="com.muchammadagunglaksana.navcontroller.MainActivity"
android:label="activity_main" tools:layout="#layout/activity_main"/>
</navigation>
and here is my MainActivity class:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navController = Navigation.findNavController(this, R.id.nav_host_fragment)
setupBottomNavMenu(navController)
setupActionBar(navController)
}
private fun setupBottomNavMenu(navController: NavController) {
bottom_nav?.let {
NavigationUI.setupWithNavController(it, navController)
}
}
private fun setupActionBar(navController: NavController) {
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_toolbar, menu)
return true
}
}
what went wrong in here?
It is because you are adding the same activity(mainActivity) as your start destination inside nav host fragment that is also part of main activity.
Solution is you have to remove main activty as your starting destination and add anotehr fragment/activity in it. like this:
<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/navigation_graph"
app:startDestination="#id/mainFragment">
<fragment android:id="#+id/mainFragment"
android:name="com.cinderellaman.general.ui.fragments.MainFragment"
android:label="main_fragment"
tools:layout="#layout/main_fragment"/></navigation>