NavigationView with a NestedScrollView inside does not fling - android

I have a NavigationView with a NestedScrollView that contains another NavigationView for the purpose of adding a footer for the NavigationView. The layout code is as follows:
<include layout="#layout/main_content"/>
<android.support.design.widget.NavigationView ...>
<android.support.v4.widget.NestedScrollView
...
android:fillViewport="true"
android:scrollbars="vertical">
<LinearLayout
...
android:orientation="vertical">
<android.support.design.widget.NavigationView
...
app:elevation="0dp"
app:headerLayout="#layout/nav_header"
app:menu="#menu/nav_menu">
</android.support.design.widget.NavigationView>
<LinearLayout
android:id="#+id/spacer_to_bottom"
...
android:layout_height="0dp"
android:layout_weight="1">
</LinearLayout>
<include layout="#layout/nav_footer"></include>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.NavigationView>
Check the full code here: https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml
The problem is that the scrolling in the NavigationDrawer is not smooth (does not "fling"). In other words, it scrolls while your finger is on the screen and stops when you remove your finger.
I tried disabling nested scroll for the first child (the LinearLayout) of the NestedScrollView but this didn't work.
Any help would be appreciated.

After some investigations I realized that the first child of the navigation view is a RecyclerView. Disabling nested scrolling on that view resolves the issue
ViewCompat.setNestedScrollingEnabled(navigationView.getChildAt(0), false);

There is another way to handle this nested scroll that is;
if you are using nestedscroll view, and using one or more list views/recycler views inside it, we have to enable this;
yourlistview.setNestedScrollingEnabled(true);
It should work now.

Related

BottomNavigationView not reacting to scrolling inside fragment, if fragment contains AppBarLayout

I'm having a lot of problems with scrolling and detection of it inside fragments using coordinatorLayout in Android.
I have a "Main Activity" that has inside it 3 fragments. Only on one of those fragments I want to have Appbar that collapses when fragment is scrolled. I've managed to do that, but if i set scrolling beahivour 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 (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 AppBarLyout 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 in fragment.
Any sort of help would be appreciated, I'm losing my mind over this for 3 straight days.

Scrollable Recycler view and view pager

I have a screen where i need to display a toolbar at the top, a slideshow below the toolbar and a recyclerview below the slideshow.
For displaying the slideshow I am using a viewPager which slides images horizontally.
The problem I am currently facing is that when the recyclerview is scrolled the viewPager needs to scroll with it and the toolbar should stay pinned.
I tried putting the viewPager and the recyclerview inside a nested Scroll but since a nested scroll requires a single child i had to put both the viewpager and recyclerview inside a linear layout because of which the scrolling behaviour of the recyclerview went for a toss ( i am monitoring the recyclerview scroll so i can load more results when it reaches the bottom ).
You can solve this problem by using CoordinatorLayout, AppBarLayout, and CollapsingToolbarLayout. You put your Toolbar and ViewPager in the CollapsingToolbarLayout, and you use the RecyclerView as the scrolling sibling to the AppBarLayout so that it can correctly collapse the ViewPager.
Here's some example XML I used to achieve what I think you described:
<android.support.design.widget.CoordinatorLayout
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">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="?attr/actionBarSize"/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layoutManager="LinearLayoutManager"/>
</android.support.design.widget.CoordinatorLayout>
The only tricky bit is that the <Toolbar> tag has to come after the <ViewPager> tag, since they're both inside a view that derives from FrameLayout. Normally, this would mean that the toolbar obscures the top portion of the viewpager, but the viewpager's marginTop attribute stops that from happening.

How to fix footer properly which is inside CoordinatorLayout

I tend to further elaborate from this
Android - footer scrolls off screen when used in CoordinatorLayout
and
https://code.google.com/p/android/issues/detail?id=177195
I wish to hide TabLayout while performing scrolling on RecyclerView. That's why I have the following layout.
<CoordinatorLayout>
<CollapsingToolbarLayout>
<TabLayout>
<ViewPager>
<RecyclerView>
<Footer>
For my situation, I have a ViewPager which contains multiple fragments.
Most of the fragments, contains RecyclerView and footer. They look like the following
<LinearLayout>
<RecyclerView />
<LinearLayout id="#+id/footer" />
</LinearLayout>
Unfortunately, the footer is movable when scrolling, although I would like it to be static.
Note, it is important to have app:layout_behavior to place in ViewPager instead of RecyclerView. If not, TabLayout will not appear.
My implementation is as follow
my_fragment.xml
<?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"
android:id="#+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" >
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="?attr/portfolioTabIndicatorColor" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="org.yccheok.xxx.CustomScrollingViewBehavior"
/>
</android.support.design.widget.CoordinatorLayout>
The very key class is org.yccheok.xxx.CustomScrollingViewBehavior, which is copied and pasted from https://stackoverflow.com/a/33396965/72437
org.yccheok.xxx.CustomScrollingViewBehavior is the best solution I can find so far. However, it is far from perfect, as it yields the following behavior.
It causes flickering, when you scroll up a little, and release your finger. Please refer to the following video.
https://youtu.be/8RvCZJeQvS0
I was wondering, based on proposed solution at https://stackoverflow.com/a/33396965/72437, is there any further improvement I can done on CustomScrollingViewBehavior class, to avoid flickering effect?
I was able to achieve what I want, by following tutorial at
https://mzgreen.github.io/2015/02/15/How-to-hideshow-Toolbar-when-list-is-scroling%28part1%29/
http://mzgreen.github.io/2015/02/28/How-to-hideshow-Toolbar-when-list-is-scrolling%28part2%29/
The key ideas are
Don't use CoordinatorLayout
Place TabLayout and RecyclerView within FrameLayout, so that TabLayout will overlay on the top of RecyclerView
Add top padding on RecyclerView. Having android:clipToPadding="false" is important as well.
To hide/ show TabLayout during scrolling, attach HidingScrollListener to RecyclerView.
The shortcoming for this solution is that, requiresFadingEdge will no longer work on RecyclerView, due to the top padding.

Scroll behavior in nested RecyclerView with horizontal scroll

I have to create vertical RecyclerView with nested horizontal RecyclerView in every item. Everything is within CoordinatorLayout. When I scroll by tapping outside nested RecyclerView toolbar hides, but when I scroll parent Recycler by tapping on nested one toolbar stays.
Any help would be appreciated.
Here is my xml layouts:
main_activity.xml:
<android.support.design.widget.CoordinatorLayout
...>
<FrameLayout
android:id="#+id/fragment_frame"
...
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.AppBarLayout
...
android:fitsSystemWindows="true"
android:id="#+id/appbar_layout">
<include layout="#layout/toolbar"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Here is toolbar.xml :
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar"
...
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways">
<TextView .../>
</android.support.v7.widget.Toolbar>
fragment.xml:
<android.support.v7.widget.RecyclerView
...
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
And recycler_view_item.xml:
<RelativeLayout ...>
<TextView .../>
<!-- fixme(CullyCross) fix bug with hiding toolbar -->
<android.support.v7.widget.RecyclerView
...
android:scrollbars="horizontal"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</RelativeLayout>
Thanks,
Anton
As requested here is the solution I found good enough so far:
In my case I have a nestedScrollView with 4 RecyclerViews set to scroll horizontally inside. For each of those RecyclerViews I have done this programatically:
restaurantsRecylerView.setHasFixedSize(true);
restaurantsRecylerView.setNestedScrollingEnabled(false);
You probably don't want the fixedSize, not sure if it will make any difference, my list is always 25 so I can use that for performance. After having done this I can scroll without issues even when I touch on the recyclerViews
Hope it helps
Try with RecyclerView inside android.support.v4.widget.NestedScrollView.
<android.support.v4.widget.NestedScrollView
android:id="#+id/nScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Set other views of your Layout -->
</android.support.v4.widget.NestedScrollView>
Also try with different layout_scrollFlags in Toolbar and
RecylerView.setNestedScrollingEnabled(false); // set it true or false as per requirement
We can achieve this in XML
android:nestedScrollingEnabled="false"

Toggling visibility AppBarLayout views causes spacing issues for loaded Fragments

I encountered a strange problem with the new Android Design Support Librar (http://android-developers.blogspot.com.ar/2015/05/android-design-support-library.html). If I place additional content (like a LinearLayout) in an AppBarLayout along with the ToolBar and toggle the visibility of that content then switching fragments will have show a dead space at the top of the fragment content.
It appears that AppBarLayout isn't resizing the parent CoordinatorLayout correctly when visibility of the content is toggled. I have my CoordinatorLayout wrapped in the DrawerLayout. I want to toggle the visibility of the extra LinearLayout in the AppBarLayout depending on the which fragment shown.
Here is my main.xml file for the MainActivity:
<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">
<android.support.design.widget.CoordinatorLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical"">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:text="Hello"/>
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
I had a similar problem using the support design widget. I had a CoordinatorLayout inside a DrawerLayout and an AppBarLayout inside the CoordinatorLayout. I had two toolbars inside the AppBarLayout. My aim was to display a toolbar with a ViewPager displaying a recyclerview content. I wanted to swop between the toolbars when selecting items. In other words, I made one toolbar GONE while the other was visible and vise versa. Scrolling the content up would push the toolbar up off the top of the screen. Everything worked perfectly except that changing orientation would show a space for the toolbar that should be gone. I tried every hack I could think of to get rid of it but did not succeed. I then came across this post and realized that it was a bug in the support library. I then tried putting a FrameLayout in the AppBarLayout and then put the two toolbars inside the FrameLayout and NO MORE SPACE! everything now works as I intend it to work. GONE toolbars are GONE and only the visible toolbar shows, even when changing the orientation.
Hope this helps someone.

Categories

Resources