TextInputLayout и AutoCompleteTextView

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

Однако в некоторых полях ввода у меня происходит автозаполнение с использованием AutoCompleteTextView (который в IMO имеет очень противоречивое имя — «TextView» вместо «EditText» — но это уже другая история) и явно наследуется непосредственно от EditText. Таким образом, он не имеет той же функциональности, что и TextInputEditText.

Поэтому мне интересно, есть ли способ добиться той же функциональности подсказки в ландшафте (без создания моей собственной реализации TextInputAutoCompleteTextView, то есть), а также избежать выдаваемых предупреждений о ворсе. Я что-то упустил здесь? Я полагаю, я понимаю, что они не создавали собственные версии всех прямых и косвенных подклассов EditText для этой конкретной вещи, так что я должен делать свои собственные?




Ответы (7)


Немного поздно, но да, вам придется накатить собственную реализацию. Хорошая новость заключается в том, что это довольно просто. Вот как было реализовано TextInputEditText:

https://android.googlesource.com/platform/frameworks/support.git/+/master/design/src/android/support/design/widget/TextInputEditText.java

Соответственно, вот как может выглядеть TextInputAutoCompleteTextView.

public class TextInputAutoCompleteTextView extends AppCompatAutoCompleteTextView {

    public TextInputAutoCompleteTextView(Context context) {
        super(context);
    }

    public TextInputAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextInputAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        final InputConnection ic = super.onCreateInputConnection(outAttrs);
        if (ic != null && outAttrs.hintText == null) {
            // If we don't have a hint and our parent is a TextInputLayout, use it's hint for the
            // EditorInfo. This allows us to display a hint in 'extract mode'.
            final ViewParent parent = getParent();
            if (parent instanceof TextInputLayout) {
                outAttrs.hintText = ((TextInputLayout) parent).getHint();
            }
        }
        return ic;
    }
}
person chessdork    schedule 26.01.2017
comment
не работает с AndroidX com.google.android.material.textfield.TextInputLayout - person djdance; 21.03.2019
comment
В AndroidX вместо этого используйте androidx.appcompat.widget.AppCompatAutoCompleteTextView. См. ответ: stackoverflow.com/a/56753094/4568679 - person Slav; 07.10.2019
comment
Я использовал это решение, но мне нужно добавить android:theme="@style/AppTheme" в этот узел, чтобы предотвратить ошибку наполнения выпадающего содержимого. - person coyer; 15.01.2020

Теперь с AndroidX вам не нужно что-то настраивать.
Нужно просто добавить стиль компонента материала (был добавлен в 1.1.0-alpha06, см. примечания к выпуску).

<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Example TextInputLayout">

    <androidx.appcompat.widget.AppCompatAutoCompleteTextView
    style="@style/Widget.MaterialComponents.AutoCompleteTextView.FilledBox"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

</com.google.android.material.textfield.TextInputLayout> 
person R00We    schedule 25.06.2019
comment
Не работает, пишет Cannot resolve symbol '@style/Widget.MaterialComponents.AutoCompleteTextView.FilledBox'. Что я делаю не так? Я использую «com.google.android.material:material:1.0.0». - person Vadim Kotov; 24.07.2019
comment
Решено, этот стиль был добавлен в 1.1.0-alpha06, см. примечания к выпуску - person Vadim Kotov; 24.07.2019
comment
Большой! Вариант OutlinedBox также работает: @style/Widget.MaterialComponents.AutoCompleteTextView.OutlinedBox. Но Android Studio по-прежнему не обеспечивает автодополнение для обоих стилей. - person theSlyest; 22.09.2020

Основываясь на ответе chessdork, я решил более подробно остановиться на том, как вы можете включить автозаполнение с подсказкой в ​​свой проект. Вот точные шаги, которые я использовал, чтобы заставить его работать:

1) Убедитесь, что у вас есть implementation 'com.android.support:design:26.1.0' в ваших зависимостях gradle. Точное имя пакета может немного отличаться в зависимости от вашей версии SDK.

2) Скопируйте класс TextInputAutoCompleteTextView из ответа @chessdork и поместите его в общедоступный класс в своем проекте.

3) Место, где вы хотите, чтобы текст редактирования автозаполнения был в вашем макете XML. Он должен быть структурирован следующим образом:

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="16dp">
        <mycompany.views.TextInputAutoCompleteTextView
            android:id="@+id/myAutoFill"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/myHint"/>
        </android.support.design.widget.TextInputLayout>
person Shn_Android_Dev    schedule 10.06.2018

С библиотекой компонентов материалов просто используйте TextInputLayout со стилем Widget.MaterialComponents.TextInputLayout.*.ExposedDropdownMenu.

Что-то вроде:

  <com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
     android:hint="Hint..."
     ...>

       <AutoCompleteTextView
           android:background="@null"
           .../>

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

введите описание изображения здесь

person Gabriele Mariotti    schedule 06.09.2019
comment
Это сработало для меня, используя androidx.appcompat.widget.AppCompatAutoCompleteTextView. - person Carlos; 06.11.2019
comment
Работает для androidx. - person pravingaikwad07; 20.02.2020

Оба ответа (@chessdork и @Shn_Android_Dev) помогают добиться правильного поведения AutoCompleteTextView (ACTV) внутри TextInputLayout (TIL), однако я обнаружил, что между началом/концом TIL и ACTV внутри него нет пробела. как вы можете видеть на следующем изображении:

Пример того, что между ACTV и TIL нет места

Что я сделал, чтобы решить проблему, так это добавил пару значений заполнения в начало и конец TextInputAutoCompleteTextView, значения, которые сработали для меня, — это 12dp в начале и 8dp в конце, но, конечно, вы можете поиграть с этим и получить желаемый эффект. Взяв пример @Shn_Android_Dev, TextInputAutoCompleteTextView будет выглядеть так:

<mycompany.views.TextInputAutoCompleteTextView
    android:id="@+id/myAutoFill"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingStart="12dp"
    android:paddingEnd="8dp"
    android:hint="@string/myHint"/>

И вид теперь выглядит так:

Пример с правильным интервалом

person Seven    schedule 07.12.2018

Может быть, кому-то нужен код для реализации Xamarin Android.

Здесь

namespace YourNamespace
{
    public class TextInputAutoCompleteTextView : AppCompatAutoCompleteTextView
    {
        public TextInputAutoCompleteTextView(Context context) : base(context)
        {
        }

        public TextInputAutoCompleteTextView(Context context, IAttributeSet attrs) : base(context, attrs)
        {
        }

        public TextInputAutoCompleteTextView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context,
            attrs, defStyleAttr)
        {
        }

        public override IInputConnection OnCreateInputConnection(EditorInfo outAttrs)
        {
            IInputConnection ic = base.OnCreateInputConnection(outAttrs);
            if (ic != null && outAttrs.HintText == null)
            {
                IViewParent parent = Parent;
                if (parent is TextInputLayout layout)
                {
                    outAttrs.HintText = new Java.Lang.String(layout.Hint);
                }
            }

            return ic;
        }
    }
}

А в XML...

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <YourNamespace.TextInputAutoCompleteTextView
            android:id="@+id/edtDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Movements"
            android:inputType="textCapSentences" />

    </android.support.design.widget.TextInputLayout>
person Erick Velasco    schedule 10.05.2019

Простое решение - преобразовать ваш EditText в AutoCompleteTextView.

XML

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

Джава

AutoCompleteTextView autoCompleteTextView;
TextInputLayout textInputLayout = findViewById(R.id.textInputLayout);
autoCompleteTextView = (AutoCompleteTextView) textInputLayout.getEditText();
person Noman Nazir    schedule 12.09.2019