TextInputLayout и AutoCompleteTextView
Я использую TextInputLayout
в моем приложении для Android, чтобы добиться этого аккуратного эффекта плавающей метки для моих полей ввода. Я знаю, что я должен использовать TextInputEditText
а также позволяет отображать подсказки, когда в альбомном режиме и ввод заполняет весь экран.
Тем не менее, в некоторых из моих полей ввода я получил автозаполнение при использовании AutoCompleteTextView
(у которого IMO есть действительно непоследовательное имя - "TextView" вместо "EditText" - но это другая история), и это, очевидно, наследуется непосредственно от EditText
, Таким образом, он не имеет такой же функциональности, как TextInputEditText
приносит.
Поэтому мне интересно, есть ли способ достичь той же функциональности подсказки в ландшафте (не делая мой собственный TextInputAutoCompleteTextView
реализации), а также избегать появления предупреждений о линте. Я что-то здесь упускаю? Я полагаю, я понял, что они не делали пользовательских версий всех прямых и косвенных подклассов EditText
для этой конкретной вещи, так что я должен сделать свой собственный?
2 ответа
Немного поздно, но да, вам придется свернуть собственную реализацию. Хорошей новостью является то, что это довольно просто. Вот как TextInputEditText
было реализовано:
Соответственно вот что 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;
}
}
Теперь с 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>
Опираясь на ответ шахматной команды, я решил подробнее рассказать о том, как включить в свой проект автозаполнение с подсказкой. Вот точные шаги, которые я использовал, чтобы заставить это работать:
1) Убедитесь, что у вас есть implementation 'com.android.support:design:26.1.0'
в ваших зависимостях. Точное имя пакета может немного отличаться в зависимости от вашей версии 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>
С библиотекой компонентов материала просто используйте 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>
https:https://stackru.com/images/1720cbcbbbe4fbded671f0fece64c3c2325d21a3.png
Оба ответа (@chessdork и @Shn_Android_Dev) помогают добиться правильного поведения AutoCompleteTextView (ACTV) внутри TextInputLayout (TIL), однако я обнаружил, что между началом / концом TIL и ACTV внутри него нет места. как вы можете видеть на следующем изображении:
Чтобы решить эту проблему, я добавил пару дополнительных значений в начало и конец 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"/>
И вид теперь выглядит так:
Может кому-то нужен код для реализации 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>
Простое решение - преобразовать ваш 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();