23

I have a Scrollview which contains an ImageView and RecyclerView. if navigation drawer opened then closed the RecyclerView auto scrolling to top, How to stop this?

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrollViewMain"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

       <ImageView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:id="@+id/imageView_main_icons_line"
           android:src="@drawable/main_line" />

              ...


       <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView_activity_main_passenger_log"
            android:paddingBottom="2dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</ScrollView>
</RelativeLayout>
Samad
  • 1,776
  • 2
  • 20
  • 35
  • Having a RecyclerView into a ScrollView is not a good idea at all. You can easily get into a trouble with the click / swipe events by using such structure. My advice - change your design – Todor Kostov Jun 16 '16 at 06:47
  • @TodorKostov I can't , except this issue every thing is ok, the recyclerView's height is wrap_content so it is ok to put recyclerview in scrollview – Samad Jun 16 '16 at 06:53

5 Answers5

82

This problem because of recyclerView has default focus.

Solution

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:orientation="vertical">

Add android:descendantFocusability="blocksDescendants" to your immediate layout of scrollView

Rahul Devanavar
  • 3,917
  • 4
  • 32
  • 61
  • 3
    Added android:descendantFocusability="blocksDescendants" to RecyclerView's parent, which is LinearLayout, and it worked. – Petar P Feb 07 '17 at 21:21
  • 1
    Please make sure to see landerlyoung's answer below. Following this accepted answer can lead to many problems for users utilizing physical keyboards. Every Android app is usable with a hard keyboard by default, unless you blindly follow Rahul Devanavar's answer. – Android developer May 29 '18 at 15:09
  • Didn't help. I have relative layout wrapped around recyclerview. – Alex Feb 15 '19 at 17:30
  • 1
    Quite useful when if you are doing anything at view holder with handler to update the content periodically. Thanks @Rahul – Paresh Dudhat Feb 25 '21 at 17:39
30

That is because RecyclerView ALWAYS set:

setFocusableInTouchMode(true);

this is hard coded in its constructor.

so if you apply those attribute in your XML for a RecyclerView

android:focusable="false"
android:focudeableInTouchMode="false"

that would be useless, you end up with recycleView.isFocusable() == true...

so the most elegant solution is to disable foucusable for RecyclerView's Parent.

<LinearLayout
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:descendantFocusability="blocksDescendants"
    ...
    >
    <android.support.v7.widget.RecyclerView
        ...
    />
/>

or you can just simply setFocusable(false)

landerlyoung
  • 1,693
  • 17
  • 14
3

Check out clearFocus() from here Android Dev Doc.

You can set a DrawerListener to your navigation drawer and use the onDrawerStateChanged() or some of the other options from here to call clearFocus() on your RecyclerView.

Todor Kostov
  • 1,789
  • 1
  • 13
  • 20
3

Adding android:descendantFocusability="blocksDescendants" can restrict scroll to recylerview but if you have edittext inside your layout, this property can block the focus of that particular edittext too. So if you are using this property please make sure you are removing this property in your kotlin/java class once the layout loaded.

parentLayout?.descendantFocusability = FOCUS_BEFORE_DESCENDANTS (view as ViewGroup).descendantFocusability = FOCUS_BEFORE_DESCENDANTS

apurv thakkar
  • 8,608
  • 3
  • 14
  • 19
0

Just add the following code in your linear layout, works 100% ` android:descendantFocusability="blocksDescendants"

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

    <LinearLayout
        android:descendantFocusability="blocksDescendants"
        android:layout_width="match_parent"
        android:layout_height="match_parent">