Recycler view inside NestedScrollView causes scroll to start in the middle

后端 未结 11 1004
眼角桃花
眼角桃花 2020-12-12 10:07

I am getting a weird scrolling behavior when I add a RecyclerView inside a NestedScrollView.

What happens is that whenever the scrollview has more rows than can be s

相关标签:
11条回答
  • 2020-12-12 10:20

    In your LinearLayout immediate after NestedScrollView, use android:descendantFocusability in the following way

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="10dp"
            android:descendantFocusability="blocksDescendants">
    

    EDIT

    Since many of them getting this answer useful, will also provide explanation.

    The use of descendantFocusability is given here. And as of focusableInTouchMode over here. So using blocksDescendants in descendantFocusability do not allows it's child to gain focus while touching and hence unplanned behaviour can be stopped.

    As for focusInTouchMode, both AbsListView and RecyclerView calls the method setFocusableInTouchMode(true); in their constructor by default, so it is not required to use that attribute in your XML layouts.

    And for NestedScrollView following method is used:

    private void initScrollView() {
            mScroller = ScrollerCompat.create(getContext(), null);
            setFocusable(true);
            setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
            setWillNotDraw(false);
            final ViewConfiguration configuration = ViewConfiguration.get(getContext());
            mTouchSlop = configuration.getScaledTouchSlop();
            mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
            mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        }
    

    Here, setFocusable() method is used instead of setFocusableInTouchMode(). But according to this post, focusableInTouchMode should be avoided unless for certain conditions as it breaks consistency with Android normal behaviour. A game is a good example of an application that can make good use of the focusable in touch mode property. MapView, if used in fullscreen as in Google Maps, is another good example of where you can use focusable in touch mode correctly.

    0 讨论(0)
  • 2020-12-12 10:22

    I had the same issue and sovled by extending NestedScrollView and disabling focusing children. For some reason, RecyclerView always requested focus even when I just opened and closed the drawer.

    public class DummyNestedScrollView extends NestedScrollView {
    public DummyNestedScrollView(Context context) {
        super(context);
    }
    
    public DummyNestedScrollView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    
    public DummyNestedScrollView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    /**
     * Fixind problem with recyclerView in nested scrollview requesting focus
     * http://stackoverflow.com/questions/36314836/recycler-view-inside-nestedscrollview-causes-scroll-to-start-in-the-middle
     * @param child
     * @param focused
     */
    @Override
    public void requestChildFocus(View child, View focused) {
        Log.d(getClass().getSimpleName(), "Request focus");
        //super.requestChildFocus(child, focused);
    
    }
    
    
    /**
     * http://stackoverflow.com/questions/36314836/recycler-view-inside-nestedscrollview-causes-scroll-to-start-in-the-middle
     * @param direction
     * @param previouslyFocusedRect
     * @return
     */
    @Override
    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
        Log.d(getClass().getSimpleName(), "Request focus descendants");
        //return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
        return false;
    }
    }
    
    0 讨论(0)
  • 2020-12-12 10:23

    to scroll to the top, just call this in setcontentview:

    scrollView.SmoothScrollTo(0, 0);
    
    0 讨论(0)
  • 2020-12-12 10:26

    As I am late in responding, but may can help someone else. Just use the below or higher version in your app level build.gradle and the issue is removed.

    compile com.android.support:recyclerview-v7:23.2.1
    
    0 讨论(0)
  • 2020-12-12 10:27

    Just add android:descendantFocusability="blocksDescendants" on the ViewGroup inside the NestedScrollView.

    0 讨论(0)
  • In my case this code solves mine issue

    RecyclerView recyclerView = findViewById(R.id.recyclerView);
    NestedScrollView nestedScrollView= findViewById(R.id.nestedScrollView);
    
    recyclerView.setFocusable(false);
    nestedScrollView.requestFocus();
    
    //populate recyclerview here
    

    My layout contains a parent layout as NestedScrollView which has a child LinearLayout. The LinearLayout has orientation "vertical" and childs RecyclerView and EditText. Reference

    0 讨论(0)
提交回复
热议问题