Метка TextInputLayout мешает введенному тексту

В моем новом приложении для Android метка TextInputLayout появляется в том месте, где пользователь вводит ввод. Это приводит к тому, что введенный текст отображается поверх метки/подсказки:

Когда пользователь впервые загружает страницу:

Когда пользователь нажимает на ввод текста, метка сжимается в верхнем левом углу, как и ожидалось:

Когда пользователь вводит запись, он вводит метку:

У меня есть два вопроса:

  1. Каково правильное поведение в соответствии с рекомендациями по дизайну материалов?
  2. Как мне добиться такого поведения?

Вот мой файл макета:

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:theme = "@style/Theme.JobSearch"
    tools:context = ".ui.JobsDetailsFragment">

    <TextView
        android:id = "@+id/text_new_position"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "@string/new_position"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" />

    <com.google.android.material.textfield.TextInputLayout
        android:id = "@+id/textInputLayout"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toBottomOf = "@+id/text_new_position">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_title"
            android:layout_width = "match_parent"
            android:layout_height = "match_parent"
            android:hint = "@string/title"
            android:theme = "@style/Theme.JobSearch"
            app:layout_constraintTop_toTopOf = "parent" />
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toBottomOf = "@+id/textInputLayout">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_business_name"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:hint = "@string/business_name" />
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id = "@+id/position_save"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_margin = "@dimen/fab_margin"
        android:contentDescription = "@string/position_save"
        android:src = "@drawable/done"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintEnd_toEndOf = "parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Обновлять

Я попытался переместить android:hint на TextInputLayout и все еще вижу то же поведение:

    <com.google.android.material.textfield.TextInputLayout
        android:id = "@+id/title_input_layout"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:hint = "@string/title"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toBottomOf = "@+id/text_new_position">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_title"
            android:layout_width = "match_parent"
            android:layout_height = "match_parent"
            app:layout_constraintTop_toTopOf = "parent" />
    </com.google.android.material.textfield.TextInputLayout>

Для справки, вот themes.xml:

<resources xmlns:tools = "http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name = "Theme.JobSearch" parent = "Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name = "colorPrimary">@color/purple_500</item>
        <item name = "colorPrimaryVariant">@color/purple_700</item>
        <item name = "colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name = "colorSecondary">@color/teal_200</item>
        <item name = "colorSecondaryVariant">@color/teal_700</item>
        <item name = "colorOnSecondary">@color/white</item>
        <!-- Status bar color. -->
        <item name = "android:statusBarColor" tools:targetApi = "l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>

    <style name = "Theme.JobSearch.NoActionBar">
        <item name = "windowActionBar">false</item>
        <item name = "windowNoTitle">true</item>
    </style>

    <style name = "Theme.JobSearch.AppBarOverlay" parent = "ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name = "Theme.JobSearch.PopupOverlay" parent = "ThemeOverlay.AppCompat.Light" />
</resources>
app:layout_constraintTop_toTopOf = "parent" ограничение .. Не уверен, что это не на месте, так как TextInputEditText не окружен ConstraintLayout
Zain 24.12.2020 20:33

@Zain Пожалуйста, опубликуйте свое предложение в качестве ответа с более полным кодом XML. Если вы имеете в виду второй фрагмент кода, я показываю только измененную версию TextInputLayout из первого фрагмента кода.

Code-Apprentice 25.12.2020 03:21

Вы уверены, что вам нужно использовать несколько app:layout_constraints? Попробуйте удалить все app:layout_constraintStart_toStartOf = "parent" и в TextInputEditText удалите строку app:layout_constraintTop_toTopOf = "parent".

Darkman 09.05.2021 10:05

@Darkman Пожалуйста, отправьте ответ, включая любые уточняющие детали.

Code-Apprentice 10.05.2021 20:28
3
4
134
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

https://material.io/components/text-fields/android#filled-text-field

Примечание. android:hint всегда следует устанавливать в TextInputLayout, а не в EditText, чтобы избежать непреднамеренного поведения.

Я думаю, это твоя проблема.

Обновление: попробуйте этот код для первого поля:

<com.google.android.material.textfield.TextInputLayout
    android:id = "@+id/title_input_layout"
    android:layout_width = "match_parent"
    android:layout_height = "wrap_content"
    android:hint = "@string/title"
    android:theme = "@style/Theme.JobSearch"
    app:layout_constraintStart_toStartOf = "parent"
    app:layout_constraintTop_toBottomOf = "@+id/text_new_position">

    <com.google.android.material.textfield.TextInputEditText
        android:id = "@+id/text_title"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

Это удалит строку app:layout_constraintTop_toTopOf = "parent" и изменит поле высоты на android:layout_height = "wrap_content"

Спасибо за ваше предложение. Хотя это может помочь избежать других проблем, это не решает проблему, о которой я здесь спрашивал.

Code-Apprentice 24.12.2020 20:02

Ваше второе предложение все еще не работает. Может быть, это как-то связано с моей темой? Кажется, мне почему-то приходится применять android:theme ко всем TextInputLayout.

Code-Apprentice 24.12.2020 21:55
<com.google.android.material.textfield.TextInputEditText
    android:id = "@+id/text_title"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:hint = "@string/title"
    android:theme = "@style/Theme.JobSearch"
    app:layout_constraintTop_toTopOf = "parent" />

Я боюсь, что ограничение app:layout_constraintTop_toTopOf = "parent" может быть снято, поскольку TextInputEditText не является прямым дочерним элементом ConstraintLayout или, вероятно, перенесено в окружение TextInputLayout, которое является прямым дочерним элементом ConstraintLayout

Применение последнего к макету с учетом предложения @Jems

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:theme = "@style/Theme.JobSearch"
    tools:context = ".ui.JobsDetailsFragment">

    <TextView
        android:id = "@+id/text_new_position"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "@string/new_position"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" />

    <com.google.android.material.textfield.TextInputLayout
        android:id = "@+id/textInputLayout"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" 
        android:hint = "@string/title"
        app:layout_constraintTop_toBottomOf = "@+id/text_new_position">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_title"
            android:layout_width = "match_parent"
            android:layout_height = "match_parent"

            android:theme = "@style/Theme.JobSearch"/>
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:theme = "@style/Theme.JobSearch"
        android:hint = "@string/business_name"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toBottomOf = "@+id/textInputLayout">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_business_name"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"/>
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id = "@+id/position_save"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_margin = "@dimen/fab_margin"
        android:contentDescription = "@string/position_save"
        android:src = "@drawable/done"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintEnd_toEndOf = "parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Спасибо, что нашли время написать это как полный ответ. Я скопировал полный макет из вашего ответа в свое приложение, и я все еще вижу то же поведение, что и в моем исходном вопросе. Любые предложения о том, что еще попробовать?

Code-Apprentice 25.12.2020 17:34

@Code-Apprentice Большое спасибо за ваш комментарий .. Можете ли вы добавить app:hintAnimationEnabled = "true" к textInputLayout .. это поведение по умолчанию, но я боюсь, что оно может быть случайно отключено программно или что-то в этом роде .. также не могли бы вы поделиться @style/Theme.JobSearch или удалить его на некоторое время и попробуйте протестировать без него .. Я не смог воспроизвести проблему .. ваш отзыв приветствуется

Zain 25.12.2020 19:35

Насколько я могу судить, подсказка анимируется нормально, но конечная позиция после анимации такова, что подсказка и введенный текст перекрываются.

Code-Apprentice 25.12.2020 23:54

И я добавил themes.xml к моему вопросу выше. Это довольно стандартно и просто, только объявляются основные и второстепенные цвета темы.

Code-Apprentice 25.12.2020 23:58
Ответ принят как подходящий

Я воспроизвел вашу проблему, и проблема в том, что вы используете android:theme="@style/Theme.JobSearch" в своем TextInputLayout или TextInputEditText. Удалите все атрибуты android:theme из всех TextInputLayout и TextInputEditText и вместо этого используйте свой собственный стиль, который будет применяться только к вашему TextInputLayout, например style="@style/MyTextInputLayoutStyle".

Я изменил ваш макет xml, используя собственный стиль для каждого TextInputLayout, как показано ниже:

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:theme = "@style/Theme.JobSearch"
    tools:context = ".ui.JobsDetailsFragment">

    <TextView
        android:id = "@+id/text_new_position"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "@string/new_position"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" />

    <com.google.android.material.textfield.TextInputLayout
        android:id = "@+id/textInputLayout"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:hint = "@string/title"
        style = "@style/MyTextInputLayoutStyle"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toBottomOf = "@+id/text_new_position">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_title"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"/>
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:hint = "@string/business_name"
        style = "@style/MyTextInputLayoutStyle"
        app:layout_constraintStart_toStartOf = "parent"
        app:layout_constraintTop_toBottomOf = "@+id/textInputLayout">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_business_name"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content" />
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id = "@+id/position_save"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_margin = "@dimen/fab_margin"
        android:contentDescription = "@string/position_save"
        android:src = "@drawable/done"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintEnd_toEndOf = "parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

где style="@style/MyTextInputLayoutStyle" — ваш собственный стиль для TextInputLayout, как показано ниже:

<style name = "MyTextInputLayoutStyle" parent = "Widget.MaterialComponents.TextInputLayout.FilledBox">
    <item name = "boxStrokeColor">@color/text_input_box_stroke_color</item>
    <item name = "boxBackgroundColor">@android:color/white</item>
</style>

и я установил селектор цвета для вашего boxStrokeColor (@color/text_input_box_stroke_color), чтобы изменить цвет нижнего штриха подчеркивания на основе сфокусированного состояния/состояния по умолчанию, как показано ниже:

<?xml version = "1.0" encoding = "utf-8"?>
<selector xmlns:android = "http://schemas.android.com/apk/res/android">
    <item android:color = "@color/teal_200" android:state_focused = "true" />
    <item android:color = "@color/teal_200" android:state_hovered = "true" />
    <item android:color = "@android:color/darker_gray" />
</selector>

И окончательный результат после вышеуказанных изменений будет таким:

Я проверил ваше предложение удалить объявления темы из TextInputLayout. Я также удалил его из ConstraintLayout. Это решает проблему с позиционированием. Я думаю, что изначально добавил явную тему, чтобы изменить фон с серого на белый. После просмотра документации Material UI кажется, что серый фон используется по умолчанию. Я посмотрю дальше на стили по умолчанию и выясню, что я хочу сделать.

Code-Apprentice 11.05.2021 02:54

Нечего сказать, это и так очевидно. Вы должны испытать это на себе.

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:orientation = "vertical"
    android:theme = "@style/Theme.JobSearch"
    tools:context = ".ui.JobsDetailsFragment">

    <TextView
        android:id = "@+id/text_new_position"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "@string/new_position"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintTop_toTopOf = "parent" />

    <com.google.android.material.textfield.TextInputLayout
        android:id = "@+id/textInputLayout"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        app:layout_constraintTop_toBottomOf = "@+id/text_new_position">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_title"
            android:layout_width = "match_parent"
            android:layout_height = "match_parent"
            android:hint = "@string/title"
            android:theme = "@style/Theme.JobSearch" />

    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:theme = "@style/Theme.JobSearch"
        app:layout_constraintTop_toBottomOf = "@+id/textInputLayout">

        <com.google.android.material.textfield.TextInputEditText
            android:id = "@+id/text_business_name"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:hint = "@string/business_name" />

    </com.google.android.material.textfield.TextInputLayout>

 
<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id = "@+id/position_save"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_margin = "@dimen/fab_margin"
        android:contentDescription = "@string/position_save"
        android:src = "@drawable/done"
        android:layout_gravity = "right"
        app:layout_constraintBottom_toBottomOf = "parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Спасибо за ответ. Объясните на словах, какие изменения мне нужно внести?

Code-Apprentice 10.05.2021 23:47

Другие вопросы по теме