TextInputLayout提示重叠问题

时间:2015-06-15 09:01:02

标签: android android-support-library

我使用Android设计库中的TextInputLayout在EditText上显示标签。

问题是我开始使用EditText提示(标签)文本重叠实际文本(一秒钟)然后返回到它自己的位置(在EditText的顶部)

为了说明这个问题,我录制了一个简短的示例视频:https://youtu.be/gy0CzcYggxU

这是我的activity.xml:

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_margin="16dp"
  android:orientation="vertical">

<android.support.design.widget.TextInputLayout
    android:id="@+id/firstNameTextInputLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp">

  <EditText
      android:id="@+id/firstNameEditText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="@string/first_name"
      android:inputType="textCapWords"
      android:textColor="@color/textPrimary"
      android:textColorHint="@color/textSecondary"
      android:textSize="16sp"
      android:theme="@style/CustomEditText"/>
</android.support.design.widget.TextInputLayout>


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

  <EditText
      android:id="@+id/lastNameEditText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="@string/last_name"
      android:inputType="textCapWords"
      android:textColor="@color/textPrimary"
      android:textColorHint="@color/textSecondary"
      android:textSize="16sp"
      android:theme="@style/CustomEditText"/>
</android.support.design.widget.TextInputLayout>

5 个答案:

答案 0 :(得分:3)

我为此提出了一个廉价的解决方法和另一个错误。

对TextInputLayout进行子类化 请参阅addView()的代码 如果在文本视图中对文本进行充气时设置了文本,则会将提示设置为折叠并阻止动画。此代码执行一种解决方法,将临时设置文本,直到在安装过程中设置状态。作为奖励,有代码可以确保在只有一个布局传递的情况下绘制提示。

    public class TextInputLayout extends android.support.design.widget.TextInputLayout {

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

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

    @SuppressLint("DrawAllocation")
    @Override
    protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) {
        if (ViewCompat.isLaidOut(this)) {
            super.onLayout(changed, left, top, right, bottom);
        } else {
            // Workaround for this terrible logic where onLayout gets called before the view is flagged as laid out.
            // The normal TextInputLayout is depending on isLaidOut when onLayout is called and failing the check which prevents initial drawing
            // If there are multiple layout passes this doesn't get broken
            post(new Runnable() {
                @SuppressLint("WrongCall")
                @Override
                public void run() {
                    TextInputLayout.super.onLayout(changed, left, top, right, bottom);
                }
            });
        }
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (child instanceof EditText) {
            EditText editText = (EditText) child;
            if (StringUtils.isEmpty(editText.getText().toString())) {
                editText.setText("  "); // Set filler text so the initial state of the floating title is to be collapsed
                super.addView(child, index, params);
                editText.setText(""); // Set back to blank to cause the hint to animate in just in case the user sets text
                // This prevents the hint from being drawn over text that is set programmatically before the state is determined
                return;
            }
        }
        super.addView(child, index, params);
    }
}

答案 1 :(得分:1)

您可以通过一个小延迟以编程方式设置提示。这不是一个理想的解决方案,但至少它看起来比重叠提示更好。

new Handler().postDelayed(
   new Runnable() {
      @Override
      public void run () {
         textInputLayout.setHint("My hint");
      }
   }, 100
);

答案 2 :(得分:1)

对我有用的解决方法是更新这样的活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    textInputLayout.setHintAnimationEnabled(false);
    textInput.setText("sample");
    textInputLayout.setHintAnimationEnabled(true);
    ...
}

答案 3 :(得分:1)

最后找到了对问题的充分解释:

  

事实证明,添加了性能优化   Android 4.0中的框架仅允许您的视图层次结构   在活动动画开始之前一个单一的绘制过程。一旦   活动动画已结束,您的视图层次结构将被绘制   你期待~16ms。

了解详情:https://medium.com/@chrisbanes

TLDR:它是平台限制,旧版本(Marshmallow及更低版本)会出现此行为。

On Nougat动画将按预期运行,没有滞后。

答案 4 :(得分:0)

Daniel Ochoa注意到评论中的解决方法对我有用 - 为EditText设置一些文本内容的初始状态(空字符串应该这样做)。这将强制提示的初始状态。

<android.support.design.widget.TextInputLayout
    android:id="@+id/firstNameTextInputLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp">

  <EditText
      android:id="@+id/firstNameEditText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="@string/first_name"
      android:inputType="textCapWords"
      android:textColor="@color/textPrimary"
      android:textColorHint="@color/textSecondary"
      android:textSize="16sp"
      android:theme="@style/CustomEditText"
      android:text=" "/>
</android.support.design.widget.TextInputLayout>
相关问题