TextInputLayout提示重叠问题

问题描述 投票:15回答:6

我正在使用Android Design Library中的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>

android android-support-library
6个回答
2
投票

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

对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
投票

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

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

1
投票

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

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

1
投票

终于找到了问题的充分解释:

事实证明,Android 4.0中的框架中添加了一个性能优化,它允许在启动Activity动画之前,您的视图层次结构只有一个绘制通道。活动动画结束后,您的视图层次结构将按照您的预期每隔~16毫秒绘制一次。

阅读更多:https://medium.com/@chrisbanes

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

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


0
投票

我认为这可以修复为编译'com.android.support:design:23.0.1'


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>
© www.soinside.com 2019 - 2024. All rights reserved.