Search code examples
javaandroidandroid-layoutandroid-edittextandroid-nestedscrollview

EditText not scrollable inside NestedScrollView


Layout: I have an EditText and 2 RecyclerViews inside a NestedScrollView, which are not visible (visibility=gone)

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    //... toolbar

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.core.widget.NestedScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="?attr/actionBarSize"
            android:fillViewport="true"
            android:scrollbars="vertical">

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

                <EditText
                    android:id="@+id/editText"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:backgroundTint="@android:color/transparent"
                    android:gravity="top"
                    android:inputType="textMultiLine|textCapSentences"
                    android:padding="@dimen/activity_margin"
                    android:singleLine="false" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv_items"
                    android:padding="@dimen/activity_margin"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scrollbars="vertical"
                    android:visibility="gone" />
   
                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv_Labels"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="12dp"
                    android:visibility="gone" />

            </LinearLayout>

        </androidx.core.widget.NestedScrollView>
        
    </LinearLayout>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/coordinator_layout"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_gravity="bottom"
        android:layout_marginBottom="?actionBarSize" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
            //...
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

The problem: When I enter more text than the height of the screen, the EditText is scrolled down to where the cursor is. But when I try to scroll up, nothing happens. Here's a screen recording I made.

Can't scroll:

  • after entering/pasting long text for the 1st time.

Can scroll:

  • after reopening the activity with text already entered
  • after closing the keyboard
  • after closing the keyboard and opening it again

Searching for similar problems yielded:

...

editText.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.getId() == R.id.editText) {
            v.getParent().requestDisallowInterceptTouchEvent(true);
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
                v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
        }
        return false;
    }
});

That solution doesn't work:

  1. The questions are about ScrollViews, not NestedScrollViews. And NestedScrollView is one of the proposed solutions (which I already use)
  2. When I add the above code, the EditText is sort of scrollable, but only when the keyboard is shown. If it is not, then it's impossible to scroll - trying to scroll causes text to be selected.
  3. Scrolling (with the keyboard open) moves the cursor.

Please let me know if you need any more info or if I've missed anything. Thank you!


Solution

  • The answer is actually simpler than I thought. After pasting your xml (and making the necessary changes for it to build - missing dimens. etc...) I just changed the height of your EditText to wrap_content and the bug was gone.

    The answer lies here: Comparing the measurements of the EditText at different points in time, on the left with height=match_parent and on the right with height=wrap_content

    On the left: The EditText is drawn on screen empty with a certain size, you paste the text and it's size doesn't change. Showing/Hiding the keyboard is one important event in the life of a screen, it's called a configuration change this causes elements to be measured again and re-drawn.

    On the right: If you change the height of the EditText to wrap_content it will force a measure and re-draw immediately after insertion.

    Measurement of EditText at different times

    Hope this helps :)