In android, I want to set nav menu dynamically according to user.
some user has 3 menus and another usr has only one menu and so on....
how can I set navigation menu dynamically? the setting of the nav menu is written in xml file. I want to set the nav menu in class file and use show and hide the menu
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
private lateinit var drawerLayout: DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupNavigationDrawer()
setSupportActionBar(toolbar)
navController = Navigation.findNavController(this,
R.id.nav_fragment
)
appBarConfiguration = AppBarConfiguration
.Builder(R.id.homeFragment, R.id.secondFragment)
.setDrawerLayout(drawerLayout)
.build()
nav_fragment.navGraphViewModels<>()
setupActionBarWithNavController(navController, appBarConfiguration)
navigation_view.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.nav_fragment).navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
private fun setupNavigationDrawer() {
drawerLayout = (findViewById<DrawerLayout>(R.id.drawer_layout))
.apply {
setStatusBarBackground(R.color.colorPrimaryDark)
}
}
}
<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"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="#+id/nav_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph"/>
</LinearLayout>
<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:headerLayout="#layout/nav_header"
app:menu="#menu/nav_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>
Make a custom navigation view like below and change Visibility of view according to your condition.
<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" >
<LinearLayout
android:background="#FFFFFF"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/layout_home"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_48dp">
<ImageView
android:id="#+id/nav_home"
app:srcCompat="#drawable/ic_home"
android:layout_width="#dimen/setting_icon"
android:layout_height="#dimen/setting_icon"
android:layout_marginLeft="#dimen/padding_double"
android:layout_marginRight="#dimen/padding_normal"
android:layout_centerVertical="true"
android:clickable="false"
android:focusable="false"
android:tint="#color/color_f85200"
android:layout_gravity="center_vertical"/>
<TextView
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/nav_home"
android:text="#string/title_activity_home"
android:textSize="16sp"
android:clickable="false"
android:focusable="false"
android:fontFamily="#font/sarabun_medium"
android:layout_marginLeft="#dimen/padding_double"
android:layout_gravity="center_vertical"
android:textColor="#color/DrawerTextColor"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
</com.google.android.material.navigation.NavigationView>
Related
I have a HomeActivity which initiates the ActionBarDrawerToggle as follows:
private fun initDrawer() {
val toolbar = binding.fragmentHomeContainerView.findViewById<MaterialToolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
drawerToggle = ActionBarDrawerToggle(
this,
binding.drawer,
toolbar,
R.string.open_drawer,
R.string.close_drawer
)
binding.drawer.addDrawerListener(drawerToggle)
drawerToggle.syncState()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
binding.navigationView.setNavigationItemSelectedListener {
handleNavigationItemSelected(it)
true
}
}
The toolbar in question is inside a Fragment. Everything's normal and working until here, the toolbar is like Gmail's search with the hamburguer icon. But when I navigate to another fragment (that doesn't have this toolbar, but instead has an arrow back button), and then navigate back again to the first fragment (the one that has the toolbar) the icon doesn't work anymore. What's the best/correct solution for this? I've tried moving the initDrawer() function within the fragment but the application frozes when creating the ActionBarDrawerToggle I assume because of the activity passed to the ActionBarDrawerToggle
drawerToggle = ActionBarDrawerToggle(
activity = (requireActivity() as HomeActivity),
...
)
Moving the toolbar from the Fragment to the Activity isn't a solution neither, not because it doesn't fix the problem (which I'm not sure) but because I need the toolbar inside the fragment.
Minimal reproducible code:
MainActivity.kt:
class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
private lateinit var drawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
override fun onStart() {
super.onStart()
initDrawer()
}
private fun initDrawer() {
val toolbar = binding.fragmentContainerView.findViewById<MaterialToolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
drawerToggle = ActionBarDrawerToggle(
this,
binding.drawer,
toolbar,
R.string.app_name,
R.string.app_name
)
binding.drawer.addDrawerListener(drawerToggle)
drawerToggle.syncState()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_home" />
</androidx.constraintlayout.widget.ConstraintLayout>
<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"
android:clipToPadding="false"
android:visibility="visible" />
</androidx.drawerlayout.widget.DrawerLayout>
Fragment1.kt:
class Fragment1 : Fragment(R.layout.fragment_1) {
private val binding: Fragment1Binding by lazy {
Fragment1Binding.bind(requireView())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.button.setOnClickListener {
navigateToFragment2()
}
}
private fun navigateToFragment2() {
val action = R.id.navigateToFragment2
Navigation.findNavController(requireView()).navigate(action)
}
}
fragment_1.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:id="#+id/entity_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment1">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:background="#android:color/transparent"
android:elevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_margin="6dp"
android:background="#drawable/rounded_toolbar"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
app:navigationIcon="#drawable/ic_baseline_menu_24"
app:titleTextColor="#android:color/white">
<EditText
android:id="#+id/entities_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="Search for client"
android:background="#android:color/transparent"
android:hint="search"
android:inputType="textPersonName"
android:minHeight="48dp"
android:textColorHint="#color/black" />
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Navigate to fragment 2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment2.kt:
class Fragment2 : Fragment(R.layout.fragment_2) {
private val binding: Fragment2Binding by lazy {
Fragment2Binding.bind(requireView())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setActionBarAction()
}
private fun setActionBarAction() {
val action = R.id.navigateToFragment1
binding.toolbar.setOnClickListener {
Navigation.findNavController(it).navigate(action)
}
}
}
fragment_2.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:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment2">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginStart="4dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="#android:color/transparent"
android:elevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:liftOnScroll="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:clickable="true"
android:focusable="true"
android:minHeight="?attr/actionBarSize"
app:contentInsetStartWithNavigation="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="#drawable/ic_baseline_chevron_left_32"
app:titleTextColor="#android:color/white">
</com.google.android.material.appbar.MaterialToolbar>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/app_bar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="34sp"
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.appbar.AppBarLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Navigate back with the arrow button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
nav_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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_home"
app:startDestination="#id/fragment1">
<fragment
android:id="#+id/fragment1"
android:name="com.example.myapplication.Fragment1"
android:label="fragment_1"
tools:layout="#layout/fragment_1" >
<action
android:id="#+id/navigateToFragment2"
app:destination="#id/fragment2" />
</fragment>
<fragment
android:id="#+id/fragment2"
android:name="com.example.myapplication.Fragment2"
android:label="fragment_2"
tools:layout="#layout/fragment_2" >
<action
android:id="#+id/navigateToFragment1"
app:destination="#id/fragment1" />
</fragment>
</navigation>
I'm developing an Android app that follows the single activity pattern. In one of my fragments I have a RecyclerView and in the case where the user scrolls down I want to hide my BottomNavigationView.
I have already seen other posts about this matter but none of them seems to help my with my issue. So far I've tried making the bottom nav view and my host fragment childs of CoordinatorLayout as well as adding the app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" property on my BottomNavigationView. I have also tried to implement this behaviour manually in code but that is not working either.
Here is my activity.xml which contains my BottomNavigationView and my host fragment.
<?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"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<fragment
android:id="#+id/fragmentMaster"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#id/bottomNav"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNav"
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/menu_bottom_nav">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
And this is the fragment with the RecyclerView
<?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"
xmlns:tools="http://schemas.android.com/tools">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/topAppBar"
style="#style/Widget.MaterialComponents.Toolbar.Primary"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll"
app:title="#string/app_name" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:scrollbars="none"
app:layout_scrollFlags="scroll">
<com.google.android.material.chip.ChipGroup
android:id="#+id/filterChips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
app:singleLine="true">
<com.google.android.material.chip.Chip
android:id="#+id/breakfastChip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="#string/breakfast" />
<com.google.android.material.chip.Chip
android:id="#+id/mealChip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="#string/meal" />
<com.google.android.material.chip.Chip
android:id="#+id/dinnerChip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="#string/dinner" />
<com.google.android.material.chip.Chip
android:id="#+id/veganChip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="#string/vegan" />
<com.google.android.material.chip.Chip
android:id="#+id/vegetarianChip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="#string/vegetarian" />
<com.google.android.material.chip.Chip
android:id="#+id/regularChip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="#string/regular" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recipeList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:listitem="#layout/item_recipe_list">
</androidx.recyclerview.widget.RecyclerView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/newRecipeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:contentDescription="#string/add_recipe"
android:src="#drawable/ic_baseline_add_24">
</com.google.android.material.floatingactionbutton.FloatingActionButton>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
Edit: The issue was that the inner CoordinatorLayout was consuming the scroll event and so the AppBarLayout worked as expected, but the outer CoordinatorLayout that manages the BottomNavView never received the scroll notification. The solution is to overwrite the CoordinatorLayout implementation so that it propagates to the parent CoordinatorLayout.
Preview
Create kotlin class NavigationViewBehavior.kt
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import androidx.core.view.ViewCompat.NestedScrollType
import com.google.android.material.bottomnavigation.BottomNavigationView
class NavigationViewBehavior : CoordinatorLayout.Behavior<BottomNavigationView>() {
private var height = 0
override fun onLayoutChild(parent: CoordinatorLayout, child: BottomNavigationView, layoutDirection: Int): Boolean {
height = child.height
return super.onLayoutChild(parent, child, layoutDirection)
}
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView, directTargetChild: View, target: View,
axes: Int, type: Int): Boolean {
return axes == ViewCompat.SCROLL_AXIS_VERTICAL
}
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout, child: BottomNavigationView,
target: View, dxConsumed: Int, dyConsumed: Int,
dxUnconsumed: Int, dyUnconsumed: Int,
#NestedScrollType type: Int) {
if (dyConsumed > 0) {
slideDown(child)
} else if (dyConsumed < 0) {
slideUp(child)
}
}
private fun slideUp(child: BottomNavigationView) {
child.clearAnimation()
child.animate().translationY(0f).duration = 200
}
private fun slideDown(child: BottomNavigationView) {
child.clearAnimation()
child.animate().translationY(height.toFloat()).duration = 200
}
}
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:id="#+id/business_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hardwareAccelerated="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinator_business_layout"
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">
<FrameLayout
android:id="#+id/frame_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?actionBarSize"
android:orientation="vertical">
<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/mobile_navigation"
tools:ignore="FragmentTagUsage" />
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
android:background="#color/colorWhite"
app:itemBackground="#drawable/border_bottom_ver"
app:itemIconTint="#drawable/tab_color"
app:itemTextColor="#drawable/tab_color"
app:menu="#menu/bottom_nav_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
call in MainActivity.kt
val navController = Navigation.findNavController(this,
R.id.nav_host_fragment)
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration!!)
NavigationUI.setupWithNavController(navView!!, navController)
val layoutParams = navView!!.getLayoutParams() as CoordinatorLayout.LayoutParams
layoutParams.behavior = NavigationViewBehavior()
val params = frameLayout.layoutParams as ViewGroup.MarginLayoutParams
//hide bottom navigation no need while sun activities are being used
navController.addOnDestinationChangedListener { controller: NavController?,
destination: NavDestination, arguments: Bundle? ->
if (destination.id == R.id.navigation_fragments ) {
params.setMargins(0, 0, 0, 0)
frameLayout.layoutParams = params
navView!!.setVisibility(View.GONE)
} else {
params.setMargins(0, 0, 0, 160)
frameLayout.layoutParams = params
navView!!.setVisibility(View.VISIBLE)
}
}
home_fragment.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" >
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvServices"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:visibility="visible" />
<TextView
android:id="#+id/no_values_assigned_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="#string/no_values_assigned"
android:textSize="#dimen/fontSizeReg"
android:textStyle="bold"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
this is the setting my RecyclerView
private fun RecyclerSetting(view: View) {
no_value = view.findViewById(R.id.no_values_assigned_message)
rvItem = view.findViewById(R.id.rvServices)
rvItem!!.setHasFixedSize(true)
//Very IMP This Line
val manager = GridLayoutManager(activity, 2,
GridLayoutManager.VERTICAL,
false)
data
rvItem!!.setLayoutManager(manager)
}
while you scroll recycler view auto-hide and also you can hide bottom navigation from specific Fragment code included
Hi I am trying to launch an activity which has a navigation drawer and it is simply a Constraintlayout with 4 buttons. But it shows a white screen. My other activities appear perfectly. I don't really know why this happened. It happened before when I was trying to build a gridlayout but now it's just a plain constraintlayout and it still appears the same. If you have any idea, thank you so much!
Here is the XML of a normal layout that works perfectly:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleTextColor="#android:color/white"
android:background="?attr/colorPrimary">
</androidx.appcompat.widget.Toolbar>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProfileActivity">
<TextView
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile"
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/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:clipToPadding="false"
app:menu="#menu/main_menu"
/>
</androidx.drawerlayout.widget.DrawerLayout>
Here is the XML of the layout that has launching problems :
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:titleTextColor="#android:color/white" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="150dp"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/textView3"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="150dp"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/textView5" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintEnd_toStartOf="#+id/textView"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textView4"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<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"
android:clipToPadding="false"
app:menu="#menu/main_menu"
/>
</androidx.drawerlayout.widget.DrawerLayout>
Here is MainActivity:
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
val drawer = findViewById<DrawerLayout>(R.id.drawer)
val drawerToggle = ActionBarDrawerToggle(this, drawer, R.string.open, R.string.close)
drawer.addDrawerListener(drawerToggle)
drawerToggle.syncState()
val navView= findViewById<NavigationView>(R.id.navigation_view)
navView.setNavigationItemSelectedListener{
when(it.itemId){
R.id.nav_profile -> {
var intent = Intent(this, ProfileActivity::class.java)
startActivity(intent)
}
R.id.nav_home -> {
var intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
R.id.nav_schedule -> {
var intent = Intent(this, ScheduleActivity::class.java)
startActivity(intent)
}
R.id.nav_settings -> {
var intent = Intent(this, SettingsActivity::class.java)
startActivity(intent)
}
R.id.nav_tutorial -> {
var intent = Intent(this, TutorialActivity::class.java)
startActivity(intent)
}
R.id.nav_about -> {
var intent = Intent(this, AboutActivity::class.java)
startActivity(intent)
}
R.id.nav_procrastination -> {
var intent = Intent(this, ProcrastinationActivity::class.java)
startActivity(intent)
}
R.id.nav_premium -> {
var intent = Intent(this, PremiumActivity::class.java)
startActivity(intent)
}
}
true
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
// override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
// val drawer = findViewById<DrawerLayout>(R.id.drawer)
// when (menuItem.itemId) {
// R.id.nav_profile -> {
// Intent(this,ProfileActivity::class.java)
// }
// }
// drawer.closeDrawer(GravityCompat.START)
// return true
// }
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val drawer = findViewById<DrawerLayout>(R.id.drawer)
val drawerToggle = ActionBarDrawerToggle(this, drawer, R.string.open, R.string.close)
if(drawerToggle.onOptionsItemSelected(item)){
return true
}
return super.onOptionsItemSelected(item)
}
override fun onBackPressed() {
val drawer = findViewById<DrawerLayout>(R.id.drawer)
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
}
I had just created by mistake a v21 layout file for my activity. This one didn't had any xml code inside. And as my phone is higher than API 21 therefore i always got a white screen. I just deleted the file and it worked out.
I need to show the text "Peek" at the collapsed state, but it shows the whole height.
How to hide the blank area above "Peek"?
It must show the "Peek" area at the first, then show "Content" after expand.
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bottom_sheet"
app:layout_behavior="#string/bottom_sheet_behavior"
app:behavior_hideable="true"
android:background="#drawable/rounded_bottom_dialog"
app:behavior_peekHeight="80dp"
android:orientation="vertical"
>
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:textColor="#color/white"
android:text="Peek" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:textColor="#color/white"
android:text="Content" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
You need to apply bottom_sheet_behavior to root view.
<?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"
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="300dp"
app:behavior_hideable="false"
app:behavior_peekHeight="80dp"
app:layout_behavior="#string/bottom_sheet_behavior">
<FrameLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#121212">
<TextView
android:id="#+id/peekView"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:text="Peek"
android:textColor="#color/white" />
<TextView
android:id="#+id/contentView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="Content"
android:textColor="#color/white" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
You can change the alpha properties of both content and peek views by slideOffset in BottomSheetCallback
class MainActivity : AppCompatActivity() {
private lateinit var bottomSheetBehavior: BottomSheetBehavior<ConstraintLayout>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
contentView.alpha = 0f
peekView.alpha = 1f
bottomSheetBehavior.addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
contentView.alpha = slideOffset
peekView.alpha = 1 - slideOffset
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
}
})
}
}
Result
I am using Navigation view with drawer layout and a custom layout in side Navigation view as menu, and included it inside navigation view but noting is visible, i have also tried to add other type of views but nothing is showing in navigationview.
below is the main activity xml code where i am using the drawerlayout and navigation view and main activity class
Main Activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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"
tools:context="com.example.minhasoft_pc.drawer.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4"
android:orientation="vertical">
<ImageView
android:layout_margin="10dp"
android:layout_gravity="center"
android:src="#mipmap/ic_launcher_round"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:layout_margin="5dp"
android:layout_gravity="center"
android:src="#mipmap/ic_launcher_round"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:layout_margin="10dp"
android:layout_gravity="center"
android:src="#mipmap/ic_launcher_round"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:layout_marginEnd="-65dp"
android:layout_marginRight="-65dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/drawer_menu"/>
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
Activity class
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerlayout ;
private ActionBarDrawerToggle mToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ActionBar bar = getActionBar();
// bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#0000ff")));
mDrawerlayout = (DrawerLayout) findViewById(R.id.Drawer) ;
mToggle = new ActionBarDrawerToggle(this,mDrawerlayout,R.string.draweropen,R.string.drawerclosed) ;
mDrawerlayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mToggle.onOptionsItemSelected(item))
{
return true ;
}
return super.onOptionsItemSelected(item);
}
}
You have to include your Nav. Drawer menu items like this , Check the below xml code as references :
Here included as app:menu="#menu/nav_drawer_items"
You can take the reference of this question with solution : Align custom view to left of navigation drawer
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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">
<android.support.design.widget.NavigationView
android:id="#+id/nav1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:menu="#menu/nav_drawer_items"
app:itemBackground="#color/app_bg_color"
app:itemIconTint="#color/text_white"
app:itemTextColor="#color/text_white"
android:background="#color/bottom_navigation_color"
android:fitsSystemWindows="true"
android:theme="#style/NavigationView" />
</android.support.v4.widget.DrawerLayout>