I'm having a lot of problems with scrolling and detection of it inside fragments using coordinatorLayout in Android. I have a "MainActivity" that contains 3 fragments. In one of those fragments I have an Appbar that collapses when fragment is scrolled. I've managed to do that, but if I set scrolling behavior to allow that, my bottomNavigationView (which is found in mainactivity.xml) does NOT react to scrolling. Codes go something like this:
Fragment1.xml
<android.support.design.widget.CoordinatorLayout
...
...>
<android.support.design.widget.AppBarLayout
...
...>
<android.support.design.widget.CollapsingToolbarLayout
app:layout_scrollFlags="scroll|exitUntilCollapsed"
...>
<android.support.v7.widget.Toolbar
.../>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
MainActivity.xml
<android.support.design.widget.CoordinatorLayout
.../>
<FrameLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
.../>
<android.support.design.widget.BottomNavigationView
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
.../>
</android.support.design.widget.CoordinatorLayout>
Now, this works well enough, in the sense that when I scroll inside fragment my AppBar collapses into the title (which is what I want), BUT my bottomNavigationView does not react to scrolling.
What I found out is that if i add the line
app:layout_behavior="@string/appbar_scrolling_view_behavior"
to the AppBarLayout xml declaration I get the bottomView to collapse on scroll event (when I scroll up it shows again). So basically either I have the ability to collapse appbar inside fragment OR I have the ability to hide BottomNavigationView when I detect a scroll event inside the fragment.
Any sort of help would be appreciated.
In order to hide bottom navigation in reaction to scrolling inside the fragement
modify onCreateView
method on fragment1.kt as follows
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
...
// access the bottom nav which is on the main activity
val bottomNav: BottomNavigationView = activity!!.findViewById(R.id.bottom_nav)
// hide bottom nav when scrolling
rvList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0 || dy < 0) {
bottomNav.visibility = View.GONE
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
bottomNav.visibility = View.VISIBLE
}
super.onScrollStateChanged(recyclerView, newState)
}
})
return view
}
In Java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
// access the bottom nav which is on the main activity
BottomNavigationView bottomNav = getActivity.findViewById(R.id.bottom_nav);
// hide bottom nav when scrolling
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if (dy > 0 ||dy<0)
{
bottomNav.setVisibility(View.GONE);
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
if (newState == RecyclerView.SCROLL_STATE_IDLE)
{
bottomNav.setVisibility(View.VISIBLE);
}
super.onScrollStateChanged(recyclerView, newState);
}
});
return view;
}
Update:
Extract the listener code to a separate function as given below (in Kotlin)
public fun hideBottomNav(
rvList: RecyclerView,
bottomNav: BottomNavigationView
) {
rvList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0 || dy < 0) {
bottomNav.visibility = View.GONE
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
bottomNav.visibility = View.VISIBLE
}
super.onScrollStateChanged(recyclerView, newState)
}
})
}