material-components-android
material-components-android copied to clipboard
[TextInputLayout] Prevents from Scrolling over the error (via setError())
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.)
Hi, can you provide more details? By "scroll", you mean using keyboard to change focused view, or swiping over the views?
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.
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.
@DannyS86 friendly ping, could you please provide a video and/or a sample app to help us debug this issue?
@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.
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.
https://user-images.githubusercontent.com/26462425/156370240-c7c01882-cfcc-4a44-8df5-5f83bdaf5b0b.mp4
This behavior can be disabled by adding app:textInputLayoutFocusedRectEnabled="false"
to the TextInputEditText.
@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.