【问题标题】:TextInputLayout and AutoCompleteTextViewTextInputLayout 和 AutoCompleteTextView
【发布时间】:2017-01-18 18:33:56
【问题描述】:

我在我的 Android 应用程序中使用 TextInputLayout 来为我的输入字段实现整洁的浮动标签效果。我知道我也应该使用TextInputEditText 以允许在横向模式下显示提示并且输入填满整个屏幕。

但是,在我的一些输入字段中,我使用AutoCompleteTextView 进行了自动完成(IMO 的名称非常不一致——“TextView”而不是“EditText”——但这是另一回事),这显然继承了直接来自EditText。因此它没有 TextInputEditText 带来的相同功能。

所以我想知道是否有一种方法可以实现相同的横向提示功能(也就是说,无需我自己的 TextInputAutoCompleteTextView 实现)并避免产生的 lint 警告。我在这里错过了什么吗?我想我知道他们没有为这个特定的东西制作EditText 的所有直接和间接子类的自定义版本,所以我应该自己制作吗?

【问题讨论】:

    标签: android autocomplete android-edittext autocompletetextview android-textinputlayout


    【解决方案1】:

    有点晚了,但是是的,您必须推出自己的实现。好消息是,这相当简单。以下是 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;
        }
    }
    

    【讨论】:

    • 不适用于 AndroidX 的 com.google.android.material.textfield.TextInputLayout
    • 对于 AndroidX,请改用 androidx.appcompat.widget.AppCompatAutoCompleteTextView。查看答案:stackoverflow.com/a/56753094/4568679
    • 我使用了这个解决方案,但是需要在这个节点中添加android:theme="@style/AppTheme" 以防止下拉内容的膨胀错误。
    【解决方案2】:

    根据 chessdork 的回答,我想我会更详细地介绍如何将带有提示的自动填充功能整合到您的项目中。以下是我用来让它工作的确切步骤:

    1) 确保您的 gradle 依赖项中有 implementation 'com.android.support:design:26.1.0'。确切的包名称会因您的 SDK 版本而略有不同。

    2) 从@chessdork 的答案中复制TextInputAutoCompleteTextView 类,并将其放入项目中的公共类中。

    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>
    

    【讨论】:

      【解决方案3】:

      两个答案(@chessdork 和@Shn_Android_Dev)都有助于在 TextInputLayout (TIL) 中实现 AutoCompleteTextView (ACTV) 的正确行为,但是我发现 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"/>
      

      视图现在看起来像这样:

      【讨论】:

        【解决方案4】:

        也许有人需要 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>
        

        【讨论】:

          【解决方案5】:

          现在,使用 AndroidX,您无需自定义任何内容。
          只需添加材质组件样式(在1.1.0-alpha06 中添加,参见release notes)。

          <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> 
          

          【讨论】:

          • 不工作,它说Cannot resolve symbol '@style/Widget.MaterialComponents.AutoCompleteTextView.FilledBox'。我究竟做错了什么?我正在使用“com.google.android.material:material:1.0.0”。
          • 解决了,这个样式是在1.1.0-alpha06中添加的,见release notes
          • 太棒了! OutlinedBox 变体也适用:@style/Widget.MaterialComponents.AutoCompleteTextView.OutlinedBox。但是 Android Studio 仍然没有为这两种样式提供自动完成功能。
          【解决方案6】:

          对于Material Components library,只需使用带有Widget.MaterialComponents.TextInputLayout.*.ExposedDropdownMenu 样式的TextInputLayout

          类似:

            <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>
          

          【讨论】:

          • 这适用于我使用 androidx.appcompat.widget.AppCompatAutoCompleteTextView。
          • 适用于 androidx。
          【解决方案7】:

          简单的解决方案是将您的 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>
          

          Java

          AutoCompleteTextView autoCompleteTextView;
          TextInputLayout textInputLayout = findViewById(R.id.textInputLayout);
          autoCompleteTextView = (AutoCompleteTextView) textInputLayout.getEditText();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-06-08
            • 1970-01-01
            • 1970-01-01
            • 2021-06-29
            • 1970-01-01
            • 2016-10-16
            • 2019-02-09
            • 2020-09-28
            相关资源
            最近更新 更多