Within my acitivity_main.xml I have a BottomNavigationView and a collapsing top app bar and a fragment. Inside the fragment, there is a recyclerview and a FAB. My collapsing medium app bar seems to work, but the FAB doesn't hide fully. Hiding seems to work, but it shows a bit behind the bottom navigation bar. What am I doing wrong?
I've added a screenshot link below to show what it looks like. You can see there that when hovering over the fragment it shows its bottom border slightly above the bottom of the screen. Not sure why. It seems that if the fragment would expand til the bottom of the screen, the FAB would hide perfectly.
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"
tools:context=".MainActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/toolbarContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="false">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/toolbarCollapsingToolbarLayout"
style="?attr/collapsingToolbarLayoutMediumStyle"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snapMargins"
>
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbarMainActivity"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
tools:title="#string/mainActivityTitle"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:layout_margin="0dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:defaultNavHost="true"
app:navGraph="#navigation/bottom_navigation"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_menu"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"/
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_expenses.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clExpensesFragment"
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"
android:background="#color/md_theme_light_background"
tools:context=".ui.expenses.ExpensesFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clExpensesViewFilterAndTotal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:paddingVertical="10dp"
android:elevation="0dp"
android:background="#drawable/expenses_fragment_top_linearlayout"
android:gravity="center_vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!--Contains some text views places horizontally here-->
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvParentExpenseDates"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingHorizontal="10dp"
tools:listitem="#layout/list_item_parent_expenses_recyclerview"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="#id/clExpensesViewFilterAndTotal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"
tools:visibility="visible"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/btnFabAddExpense"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="0.9"
android:scaleY="0.9"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="#drawable/ic_fab_add"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity OnCreate()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightNavigationBars = true
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = true
// Setting up the binding object
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbarMainActivity)
val bottomNavigationView = binding.bottomNavigationView
val navHostFragment =supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
val navController = navHostFragment.navController
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.expensesFragment, R.id.statsFragment, R.id.settingsFragment
))
setupActionBarWithNavController(navController, appBarConfiguration)
bottomNavigationView.setupWithNavController(navController)
val color = SurfaceColors.SURFACE_2.getColor(this)
window.statusBarColor = color
window.navigationBarColor = color
binding.toolbarMainActivity.setBackgroundColor(color)
binding.toolbarCollapsingToolbarLayout.setBackgroundColor(color)
}```
[ScreenShot of activity_main.xml][1]
[1]: https://i.stack.imgur.com/2D3kT.jpg
Related
I have activity with FloatingActionButton and BottomNavigationView.
I want FloatingActionButton have position above BottomNavigationView. but no matter what I do, it is always with BottomNavigationView like on img
<?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=".MainActivity2">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
app:defaultNavHost="true"
app:navGraph="#navigation/mobile_navigation" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="#drawable/ic_baseline_addchart_24" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/yu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:menu="#menu/bottom_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Place FAB button inside the constraint layout and then set the property
app:layout_constraintTop_toBottomOf="#id/fab"
to your Navigation View and
app:layout_constraintBottom_toTopOf="#id/bottom_bar"
android:layout_margin="16dp"
In this way the FAB button will always stay on top of navigation view.
here you go just replace it with your floatbutton tag
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginBottom="70dp"
android:layout_marginEnd="16dp"
android:src="#drawable/ic_baseline_addchart_24" />
the bottom navigation is almost 56dp height so what we did is we added 70dp to marginBottom to lift it above the navigation and it will stay there always, you can change that value as your likings :)
I am trying to implement show/hide behavior of bottom navigation and collapsible toolbar from a specific fragment of bottom navigation.
Here is my activity_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"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/nav_host_fragment_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toTopOf="#id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:layout_behavior="#string/hide_bottom_view_on_scroll_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
And here is the fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purple_200">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap">
<TextView
android:id="#+id/text_header"
android:layout_width="match_parent"
android:layout_height="150dp"
android:gravity="center"
android:text="Parallax Area"
android:textSize="20sp" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Currently when I scroll, only 'Parallax Area (pink)' is showing/hiding but not bottom navigation in sync. When I remove the '#+id/text_header' then my bottom navigation also shows/hides. I want to do it for only this fragment, not for the others. I came across with nested coordinator layout implementations, none of them worked.
How can I solve this? Thanks in advance.
I just found the solution to show/hide the BottomNavigation in an Activity when scrolling a RecyclerView in a Fragment.
The core idea is to set HideBottomViewOnScrollBehavior
programmatically when you're navigating Fragments
First of all, if you're using Navigation component from Jetpack, use addOnDestinationChangedListener in the Activity witch holds the nav host to get the current showing Fragment.
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.scrollToHideFragment -> {
toggleBottomNavBehavior(true)
}
else -> {
toggleBottomNavBehavior(false)
}
}
}
In the above code, toggleBottomNavBehavior will be called when the destination has changed.
Add toggleBottomNavBehavior method in the Activity
private fun toggleBottomNavBehavior(scrollToHide: Boolean) {
// Get the layout params of your BottomNavigation
val layoutParams = binding.bottomNav.layoutParams as CoordinatorLayout.LayoutParams
// Apply LayoutBehavior to the layout params
layoutParams.behavior =
if (scrollToHide) HideBottomViewOnScrollBehavior<CoordinatorLayout>() else null
// Add margin to Nav Host Fragment if the layout behavior is NOT added
// bottom_nav_height is 56dp when using Material BottomNavigation
binding.navHostMain.updateLayoutParams<ViewGroup.MarginLayoutParams> {
setMargins(
0, 0, 0, if (scrollToHide) 0 else resources.getDimensionPixelSize(R.dimen.bottom_nav_height)
)
}
}
Now you can scroll in a Fragment and hide the BottomNav in the Activity!
here is the simple project of this problem:
https://drive.google.com/file/d/1fs7ggSdhPbiNCWa5GIb5RIIOEKQbgo57/view?usp=sharing
in my activity, as a base, I have tab layout and view pager like this
<?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=".activities.MainActivity">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout_main"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_gravity="center_horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabRippleColor="#null">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager_main"
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_toBottomOf="#+id/tabLayout_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
and here is the code for my MainActivity
class MainActivity : AppCompatActivity() {
lateinit var tabLayout : TabLayout
lateinit var viewPager: ViewPager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tabLayout = findViewById(R.id.tabLayout_main)
viewPager = findViewById(R.id.viewPager_main)
val adapter = ViewPagerAdapter(supportFragmentManager)
adapter.addFragment(AFragment(),"Fragment A")
adapter.addFragment(BFragment(),"Fragment B")
viewPager.adapter = adapter
tabLayout.setupWithViewPager(viewPager)
}
}
in one fragment of my viewpager (fragment B), there is a recycler view inside fragment B.
here is the xml for fragment B
<?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/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.BFragment" >
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewB"
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>
here is the problem .....
if I scroll vertically in that recycler view in fragment B, it does not make my tab layout in my MainActivity scrolled. the tab layout still on the top. I want to make that tab layout scrolled and disappear from the screen when I scroll the recycler view.
I have tried to set nested scroll view in my MainActivity xml, like this code below, it doesn't work
<?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=".activities.MainActivity">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#android:color/white"
android:id="#+id/scrollView_verified_user_control"
android:scrollbars="vertical"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout_main"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_gravity="center_horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabRippleColor="#null">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager_main"
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_toBottomOf="#+id/tabLayout_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
java or kotlin is ok
Try wrapping your TabLayout inside a CoordinatorLayout
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/id_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
<com.google.android.material.tabs.TabLayout
android:id="#+id/id_tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I have a Activity class, bottom navigation bar in it, 3(Home, Notification, Dashboard) fragments, and 1 more fragment(UpMenuFragment) inside Home fragment. The problem is, that when I create UpMenuFragment, bottom bar disappear
MainActivity.kt
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
android:duplicateParentState="true"
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
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="#id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<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_constraintBottom_toTopOf="#+id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
HomeFragment.kt
val upMenuFragment = UpMenuFragment.newInstance()
childFragmentManager.beginTransaction().add(R.id.home_up_menu_container,
upMenuFragment).commit()
fragment_home.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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/home_up_menu_container"
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
So, what's the problem?
the problem was that I was returning new view in fragment instead of return binding.root
My MainActivity's got a RecyclerView and a BottomNavigationView. Items in the RecyclerView are CardViews.
When I click an item that's halfway obscured by the BottomNavigationView (- will call it BNV), it "pops" over the BNV, then slides up to become the header in LaunchedActivity.
When backing out of LaunchedActivity, it slides down, over the BNV, then "snaps" back into place:
How can I either:
Have the shared content appear to slide from underneath the BNV,
or failing that,
Have the shared content start off invisible, and fade as it slides to the header
I've tried playing with the elevation of the BNV, I've tried setting sharedElementEnterTransition to Fade(), I've tried specifying excludeTarget with BottomNavigation; I can't seem to make things work how I'd like.
Here's the layout for MainActivity:
<?xml version="1.0" encoding="utf-8"?>
<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.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/navigation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
</android.support.constraint.ConstraintLayout>
Activity_launched is here:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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=".LaunchedActivity">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.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"/>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_launched"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
And content_launched:
<?xml version="1.0" encoding="utf-8"?>
<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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_launched"
tools:context=".LaunchedActivity">
<LinearLayout
android:id="#+id/launched_header"
android:transitionName="header" android:layout_width="0dp" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical" app:layout_constraintEnd_toEndOf="parent"
android:background="#android:color/holo_blue_bright"
android:layout_marginEnd="8dp">
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/launched_title"/>
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/launched_text"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Items in the RecyclerView call MainActivity.onItemClicked:
fun onItemClicked(view: View, item: Item) {
val intent = Intent(applicationContext, LaunchedActivity::class.java)
intent.putExtra("ITEM", item)
val options = ActivityOptions.makeSceneTransitionAnimation(
this,
android.util.Pair<View, String>(view, "header")
)
startActivity(intent, options.toBundle())
}
This is the array that's in the recycler:
data class Item(val title: String, val text: String): Serializable
val itemList = listOf(Item("One", "1"), Item("Two", "2"),
Item("Three", "3"), Item("Four", "4"), Item("Five", "5"))
Lastly, this is from LaunchedActivity.onCreate:
with(window) {
requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)
requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
sharedElementEnterTransition = AutoTransition()
sharedElementExitTransition = AutoTransition()
}
LaunchedActivity.onCreate pulls the item out of the intent and sets launched_title and launched_text.
Add in recyclerView's item's CardView
app:cardMaxElevation="8dp"
and give your BNV
app:elevation="16dp"
give it a try, try with more difference in elevation as clicked cardview has more elevation than actual elevation
Have you heard of clipToPadding it can add padding to the bottom views so it does not obstruct the bottom views.
So try setting clipToPadding = "true" and check if it solves.
Android what does the clipToPadding Attribute do?
Also your layout activity file has <RecyclerView> set to 0dp.
Use a <RelativeLayout> outside and set layout_above="#bnv" in <RecyclerView> somewhat similar to this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/navigation1"
android:layout_weight="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.nxtoff.plzcome.commonutills.BottomNavigationViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="#+id/viewpager"
android:background="#999999" />
</RelativeLayout>
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/navigation1"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:itemBackground="#android:color/white"
app:itemIconTint="#drawable/nav_item_colors"
app:itemTextColor="#drawable/nav_item_colors"
app:menu="#menu/navigation" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/xfb_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="bottom|center_horizontal"
android:layout_margin="22dp"
android:layout_marginBottom="30dp"
android:background="#color/colorloader"
android:clickable="true"
android:src="#drawable/plus_fab"
android:tint="#color/colorviolet"
app:backgroundTint="#color/colorloader"
app:elevation="8dp"
app:fabSize="normal"
/>
</RelativeLayout>
EDIT 1:
Try out this code and let me know.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:layout_above="#id/bottomNavigationView"
android:layout_alignParentTop="true"
android:layout_marginBottom="8dp"
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/navigation"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>