material-components-android icon indicating copy to clipboard operation
material-components-android copied to clipboard

[TextInputLayout] Prevents from Scrolling over the error (via setError())

Open sacrificium-dev opened this issue 3 years ago • 8 comments

Description: I have a TextInputLayout with an TextInoutEditText on top of my Fragments view, followed by more views, so I have to scroll and put that scrollable content within a ScrollView.

If I show an error using setError() on a TextInputLayout, I am no longer able to scroll over the EditText and let it scroll out of the ScrollView. I can't access all views below that EditText while there is an error displayed. That blocks the rest of my Fragment to be reached!

Expected behavior: If there is a TextInputLayout with an error, it should always be possible to scroll over it.

Source code:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/separator">

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

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/standard_16"
            android:layout_marginTop="@dimen/standard_16"
            android:layout_marginBottom="@dimen/standard_16"
            android:orientation="horizontal">

            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/til_reading_value"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                app:constraint_referenced_ids="button_show_photo,button_take_photo"
                app:layout_constraintEnd_toStartOf="@id/button_show_photo"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/edit_reading_value"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/read_out_value"
                    android:imeOptions="actionDone|flagNoExtractUi"
                    android:inputType="numberDecimal"
                    android:textColor="@color/colorAccent"
                    android:textSize="@dimen/default_textsize_24sp"
                    tools:ignore="Autofill" />
            </com.google.android.material.textfield.TextInputLayout>
...
textInputLayoutReadingValue = view.findViewById(R.id.til_reading_value);
private void showInputError(String err) {
    TextInputLayout textInputLayoutReadingValue = getTextInputLayoutReadingValue();
    textInputLayoutReadingValue.setError(err);
}

Android API version: Tested on API 28, 29 and 30

Material Library version: com.google.android.material:material:1.4.0

Device: Samsung Galaxy TAB 2 (Android 7.1.1)
(The error does not occur on a Samsung A9 (Android 10) for example.)

sacrificium-dev avatar Oct 19 '21 11:10 sacrificium-dev

Hi, can you provide more details? By "scroll", you mean using keyboard to change focused view, or swiping over the views?

drchen avatar Oct 19 '21 17:10 drchen

Hi, can you provide more details? By "scroll", you mean using keyboard to change focused view, or swiping over the views?

I updated the XML-example for better understanding. Let me explain in more detail:

In my ScrollView I have a LinearLayout. First there is a ConstraintLayout as first child in that LinearLayout. This ConstraintLayout contains the affected TextInputLayout. After the ConstraintLayout there are many more child views in the LinearLayout - you can reach them usually using scrolling (via swiping the ScrollView to it's bottom content). Not the entire content of the LinearLayout fits the screen.

Now, if I have a TextInputLayout with an error (setError()) I can't scroll (swipe the ScrollView) below that TextInputLayout while the error is shown. I can't reach views that are outside of the screen. The TextInputLayout with the error forces to be shown. If there is no error you can scroll to the most bottom position of the ScrollView.

Formerly there was an issue in AOSP: https://issuetracker.google.com/issues/36966708 - the solution there doesn't work, I am already setting the error on the TextInputLayout. So I followed up with opening a new Ticket https://issuetracker.google.com/u/1/issues/202761168. But they refer to this project/issue tracker.

sacrificium-dev avatar Oct 20 '21 12:10 sacrificium-dev

I tried reproducing this and I'm not encountering this error on my end (on a Pixel emulator running API level 32). Could you please provide a video of this error? Including a sample app reproducing the error would also be helpful.

afohrman avatar Feb 15 '22 21:02 afohrman

@DannyS86 friendly ping, could you please provide a video and/or a sample app to help us debug this issue?

afohrman avatar Mar 01 '22 21:03 afohrman

@afohrman sorry for delay, I was every busy. Thanks for your reminder-ping. I'll start today to collect the required information (sample-app and video). Hopefully this week I can provide it, I promise, you'll hear from me promptly.

sacrificium-dev avatar Mar 02 '22 09:03 sacrificium-dev

I wrote a sample app, essentially similar to our companies solution. We're using both, tablets and smartphones in our company, thus we're often using dual-pane-layouts on tablets in landscape-mode and single-pane on any portrait variant (even on tablets). While writing this sample-app there where new exciting insights on what causes the error to myself.

I found out, that the error does only occur on large screens in landscape (in my case >= sw600dp-land). This is an important news for reproducing it, It is reproducable with the sample app on a AVD Picel C with API 30 on landscape for example. On a Smartphone (for example an AVD of a Pixel 5 with API 30) it is not reproducable, neither in portriat, nor in landscape. The interesting part here is, that the same fragment-layout does not produce the issue in portrait.

When I figured out that the same fragment-layout works well in portrait mode, I thought it could have something to do with the Activities layout for dual pane. I tried an alternative Activity-layout (activity_main2) where I changed the root-layout from LinearLayout to androidx.constraintlayout.widget.ConstraintLayout, but it changed nothing. So it seems to be a combination of the dual-pane-layout and something with the fragment-layout.

To figure out more I started to create a new Fragment (MainNoIssueFragment), for which I copied the original fragment_main to fragment_main_no_issue. These Fragments can be switched from the options menu of the activity. In that layout I removed the ImageButton placed beside the TextInputLayout and the the error does not longer occur in landscape. But I can't get it - did I made a mistake when building the layout, I think the layout should be legitim how it was before?

The sample app is written in Java, suing targetApi 31, compile SDK 31 and minSdk 21.

issue-2435-sample-project.zip

https://user-images.githubusercontent.com/26462425/156370240-c7c01882-cfcc-4a44-8df5-5f83bdaf5b0b.mp4

sacrificium-dev avatar Mar 02 '22 13:03 sacrificium-dev

This behavior can be disabled by adding app:textInputLayoutFocusedRectEnabled="false" to the TextInputEditText.

Benjiko99 avatar Mar 29 '22 20:03 Benjiko99

@Benjiko99 thank you, but app:textInputLayoutFocusedRectEnabled="false" on the TextInputEditText doesn't solved the issue for me. The behavior stays the same as before.

It seems to have something to do with the limited space in my pane-layout scenario where the ImageButton is placed beside the TextInputLayout... While the error never occurs without that button, neither in dual-pane nor single-pane layout.

sacrificium-dev avatar Mar 30 '22 06:03 sacrificium-dev