7

I have a layout where I have a NestedScrollView containing an Image, multiple buttons and a RecycleView.

When I say recycleView.smoothScrollToPosition or recycleView.scrollToPosition() it doesn't do anything at the moment. Refuse to scroll even a pixel. If I remove the NestedScrollView it works fine, but in case I lose the scrolling effect on the surrounding areas.

Does any of you met with this problem before?

<?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" android:fitsSystemWindows="true" tools:context="world.the.rule.com.testtollbarstuff.ScrollingActivity"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="@dimen/app_bar_height" android:fitsSystemWindows="true" android:orientation="vertical" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="none" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" app:layout_collapseMode="parallax"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:clickable="true" android:src="@drawable/mock_image" /> <include layout="@layout/content_scrolling" /> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CollapsingToolbarLayout> 

4
  • I did now, but now effect at all! Commented Dec 21, 2016 at 9:53
  • 1
    in your LinearLayout add this property android:descendantFocusability="blocksDescendants". Commented Dec 21, 2016 at 9:58
  • recycleView.post(new Runnable() { public void run() { recycleView.smoothScrollToPosition(80); }); Commented Dec 21, 2016 at 9:59
  • @Karoly did my solution worked?? Commented Jan 6, 2017 at 10:57

3 Answers 3

3

If you just want smooth scroll then no custom scrolling required as I mentioned earlier in some other thread.

Add lines as below when ever you want to start smooth scroll

appBarLayout.setExpanded(false, /*true if animation required else false*/true); recyclerView.smoothScrollToPosition(position); 

Additional Info

Additionally, I don't see any RecyclerView in your layout and chances are there you have kept it in LinearLayout which is again part of CollapsingToolbarLayout. I have absolutely no idea why you have kept RecyclerView as part of CollapsingToolbarLayout. I will give a layout (simplified one) which I am using.

<?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:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.CoordinatorLayout android:id="@+id/container" 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" app:expanded="true" app:layout_behavior="com.company.app.custom.CustomRecyclerScrollBehavior"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginEnd="64dp" app:expandedTitleMarginStart="48dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <FrameLayout android:id="@+id/header_frame" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.8"> <com.company.app.custom.CustomViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="wrap_content" app:calculation="height" app:height_ratio="@integer/product_listitem_img_width_ratio" app:width_ratio="@integer/product_listitem_img_height_ratio" /> <com.company.app.custom.CustomImageView android:id="@+id/img_stock_layer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitXY" android:src="@color/transparent_app_black" android:visibility="gone" app:calculation_type="height" app:ratio_height="@integer/product_listitem_img_width_ratio" app:ratio_width="@integer/product_listitem_img_height_ratio" /> <com.inneex.www.customfonts.FontTextView android:id="@+id/lbl_out_of_stock" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/out_of_stock" android:textColor="?android:attr/textColorPrimaryInverse" android:textSize="13sp" android:visibility="gone" app:customFont="@string/font_ss_semibold" /> <LinearLayout android:id="@+id/ll_page" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:orientation="horizontal" android:paddingBottom="@dimen/inspire_detail_oval_margin_bottom" /> </FrameLayout> <android.support.v7.widget.Toolbar android:id="@+id/main_toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_height" android:background="?attr/colorPrimary" app:layout_anchor="@id/header_frame" app:layout_collapseMode="pin" app:title=""> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <com.inneex.www.customfonts.FontTextView android:id="@+id/lbl_toolbar_product_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:ellipsize="end" android:lines="1" android:maxLines="1" android:minLines="1" android:textColor="?android:attr/textColorPrimary" android:textSize="18sp" app:customFont="@string/font_ss_semibold" /> </LinearLayout> </android.support.v7.widget.Toolbar> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <ImageView android:id="@+id/img_back" android:layout_width="@dimen/toolbar_height" android:layout_height="@dimen/toolbar_height" android:layout_gravity="top|start" android:scaleType="fitXY" android:src="@drawable/back" app:layout_collapseMode="parallax" /> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout> <include layout="@layout/listitem_product_detail_buy_cheap" android:layout_width="match_parent" android:layout_height="@dimen/product_detail_button_buy_cheap_height" android:layout_alignParentBottom="true" android:layout_gravity="bottom" /> </RelativeLayout> 

FrameLayout with id header_frame is responsible for big toolbar which will collapse on scrolling. Toolbar with id main_toolbar is responsible for collapsed view of toolbar. RecyclerView is the below AppBarLayout. ImageView is for back button that will be displayed once collapsed Toolbar is displayed.

For reference, to make scroll smooth I have added CustomRecyclerScrollBehavior which I talked earlier with you. This is what it is

import android.content.Context; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.View; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; /** * Created by jimitpatel on 13/12/16. */ public class CustomRecyclerScrollBehavior extends AppBarLayout.Behavior { private Map<RecyclerView, RecyclerViewScrollListener> scrollListenerMap = new HashMap<>(); //keep scroll listener map, the custom scroll listener also keep the current scroll Y position. public CustomRecyclerScrollBehavior() { } public CustomRecyclerScrollBehavior(Context context, AttributeSet attrs) { super(context, attrs); } /** * * @param coordinatorLayout * @param child The child that attached the behavior (AppBarLayout) * @param target The scrolling target e.g. a recyclerView or NestedScrollView * @param velocityX * @param velocityY * @param consumed The fling should be consumed by the scrolling target or not * @return */ @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { if (target instanceof RecyclerView) { final RecyclerView recyclerView = (RecyclerView) target; if (scrollListenerMap.get(recyclerView) == null) { RecyclerViewScrollListener recyclerViewScrollListener = new RecyclerViewScrollListener(coordinatorLayout, child, this); scrollListenerMap.put(recyclerView, recyclerViewScrollListener); recyclerView.addOnScrollListener(recyclerViewScrollListener); } scrollListenerMap.get(recyclerView).setVelocity(velocityY); consumed = scrollListenerMap.get(recyclerView).getScrolledY() > 0; //recyclerView only consume the fling when it's not scrolled to the top } return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } private static class RecyclerViewScrollListener extends RecyclerView.OnScrollListener { private int scrolledY; private boolean dragging; private float velocity; private WeakReference<CoordinatorLayout> coordinatorLayoutRef; private WeakReference<AppBarLayout> childRef; private WeakReference<CustomRecyclerScrollBehavior> behaviorWeakReference; public RecyclerViewScrollListener(CoordinatorLayout coordinatorLayout, AppBarLayout child, CustomRecyclerScrollBehavior barBehavior) { coordinatorLayoutRef = new WeakReference<>(coordinatorLayout); childRef = new WeakReference<>(child); behaviorWeakReference = new WeakReference<>(barBehavior); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { dragging = newState == RecyclerView.SCROLL_STATE_DRAGGING; } public void setVelocity(float velocity) { this.velocity = velocity; } public int getScrolledY() { return scrolledY; } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { scrolledY += dy; if (scrolledY <= 0 && !dragging && childRef.get() != null && coordinatorLayoutRef.get() != null && behaviorWeakReference.get() != null) { //manually trigger the fling when it's scrolled at the top behaviorWeakReference.get().onNestedFling(coordinatorLayoutRef.get(), childRef.get(), recyclerView, 0, velocity, false); } } } } 

This class is used for maintaining scroll speed for RecyclerView in nested scrolls. It's fling has been changed over here

Hope this works out for you!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for adding this, it works fine on my pet project, I am implementing on my product project !
1

do this

recycleView.smoothScrollToPosition(80); 

later , not inside onCreate method , either use delayed thread or in another overide method.

example :

 new Handler().postDelayed(new Runnable() { @Override public void run() { recycleView.smoothScrollToPosition(80); } }, 150); 

2 Comments

Thanks mate, but I've already tried this adding into onPostResume. Nothing happen :(
try with the example , it must work , keep it in the oncreate and put the example there
0

Give some fixed height instead of match_parent or wrap_content to recyclerview.Because when recyclerview inside scrollview , Its height wll be the total height of its items , So this will disable the scroll of recyclerview and enable the nestedscrollview only.

6 Comments

That made sense, the scrollingToPosition works fine now, but I can't scroll the RW
sorry i didnt get your question
remove this line from your code recycleView.setNestedScrollingEnabled(false);
I did but nothing changed: the recycleview scrolling works very well now, but when I scroll it the image above doesn't get collapsed, it stays there as static.
Then use coordinator layout as your parent layout
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.