使用 FrameLayout 时,TextInputLayout 文本 header 消失了
TextInputLayout text header gone when using FrameLayout
这是我当前的 xml 布局:
<android.support.design.widget.TextInputLayout
android:id="@+id/emailAddressLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:focusable="true"
android:clickable="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:padding="5dp"
android:focusable="false"
android:clickable="false">
<AutoCompleteTextView
android:id="@+id/emailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:hint="email address"
android:inputType="textEmailAddress"
android:imeOptions="actionNext"
android:maxLines="1" />
<Button
android:id="@+id/emailTextClearButton"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_gravity="end|center_vertical"
android:background="@drawable/ic_clear_black_svg" />
</FrameLayout>
</android.support.design.widget.TextInputLayout>
我需要 FrameLayout
才能在我的 AutoCompleteTextView 中完成 (x) 清除按钮。
问题是 FrameLayout
否定了 TextInputLayout
的效果,因此当用户输入文本或单击 AutoCompleteTextView
时,文本不会被推上去。
当前结果:(缺少电子邮件地址 header 文本)
想要的结果:(我添加了一个 x 清除按钮来显示不使用 FrameLayout
时缺少的内容)
TextInputLayout
有一些内部行为并不完全符合您对 "normal" ViewGroup
的期望。其中大部分没有记录,但 the Javadoc for the class itself 确实告诉了你一点:
Note: The actual view hierarchy present under TextInputLayout
is NOT guaranteed to match the view hierarchy as written in XML. As a result, calls to getParent()
on children of the TextInputLayout
-- such as an TextInputEditText
-- may not return the TextInputLayout
itself, but rather an intermediate View
. If you need to access a View
directly, set an android:id
and use View#findViewById(int)
.
你应该从中得到的是 TextInputLayout
可能会 "re-write" 你声明的 XML 布局和你应该 也 尽力确保您的 XML 布局按照 TextInputLayout
"expects".
的方式设置
我认为您的具体问题源于这样一个事实,即您的 XML 布局没有指定 EditText
,它是 TextInputLayout
的直接子项。如果你查看 the source for TextInputLayout#addView()
,你会看到:
@Override
public void addView(View child, int index, final ViewGroup.LayoutParams params) {
if (child instanceof EditText) {
...
setEditText((EditText) child);
} else {
...
}
}
因为您有一个 FrameLayout
包装 EditText
,所以永远不会调用 setEditText()
。因此,TextInputLayout
的特殊功能的 none 将起作用。
如何解决这个问题比较难。我将从更改您的布局开始,改为使用此结构:
<FrameLayout>
<TextInputLayout>
<EditText/>
</TextInputLayout>
<Button/>
</FrameLayout>
这样你就可以有一个 "normal" TextInputLayout
层次结构 和 一个按钮来清除文本。您需要做更多的工作来定位按钮,使一切看起来自然,但这应该是一个可行的起点。
我最终在 XML 中使用以下内容解决了我的问题:
<android.support.design.widget.TextInputLayout
android:id="@+id/emailAddressTextInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<AutoCompleteTextView
android:id="@+id/emailAddress"
style="@style/body_text_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/prompt_email_address"
android:imeOptions="actionNext"
android:inputType="textEmailAddress"
android:maxLines="1"/>
<!--work around solution using negative marginTop-->
<Button
android:id="@+id/emailTextClearButton"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="end|center_vertical"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
//work around solution
android:layout_marginTop="-32dp"
android:background="@drawable/ic_clear_black_svg"/>
</android.support.design.widget.TextInputLayout>
WORKAROUND 是将我的 button
设置在我的 AutoCompleteTextView
下方,并使用 负 marginTop按钮,以便能够将其设置在需要设置的位置。
结果:
注意:我使用 RelativeLayout
作为 TextInputLayout
的父级
这是我当前的 xml 布局:
<android.support.design.widget.TextInputLayout
android:id="@+id/emailAddressLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:focusable="true"
android:clickable="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:padding="5dp"
android:focusable="false"
android:clickable="false">
<AutoCompleteTextView
android:id="@+id/emailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:hint="email address"
android:inputType="textEmailAddress"
android:imeOptions="actionNext"
android:maxLines="1" />
<Button
android:id="@+id/emailTextClearButton"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_gravity="end|center_vertical"
android:background="@drawable/ic_clear_black_svg" />
</FrameLayout>
</android.support.design.widget.TextInputLayout>
我需要 FrameLayout
才能在我的 AutoCompleteTextView 中完成 (x) 清除按钮。
问题是 FrameLayout
否定了 TextInputLayout
的效果,因此当用户输入文本或单击 AutoCompleteTextView
时,文本不会被推上去。
当前结果:(缺少电子邮件地址 header 文本)
想要的结果:(我添加了一个 x 清除按钮来显示不使用 FrameLayout
时缺少的内容)
TextInputLayout
有一些内部行为并不完全符合您对 "normal" ViewGroup
的期望。其中大部分没有记录,但 the Javadoc for the class itself 确实告诉了你一点:
Note: The actual view hierarchy present under
TextInputLayout
is NOT guaranteed to match the view hierarchy as written in XML. As a result, calls togetParent()
on children of theTextInputLayout
-- such as anTextInputEditText
-- may not return theTextInputLayout
itself, but rather an intermediateView
. If you need to access aView
directly, set anandroid:id
and useView#findViewById(int)
.
你应该从中得到的是 TextInputLayout
可能会 "re-write" 你声明的 XML 布局和你应该 也 尽力确保您的 XML 布局按照 TextInputLayout
"expects".
我认为您的具体问题源于这样一个事实,即您的 XML 布局没有指定 EditText
,它是 TextInputLayout
的直接子项。如果你查看 the source for TextInputLayout#addView()
,你会看到:
@Override public void addView(View child, int index, final ViewGroup.LayoutParams params) { if (child instanceof EditText) { ... setEditText((EditText) child); } else { ... } }
因为您有一个 FrameLayout
包装 EditText
,所以永远不会调用 setEditText()
。因此,TextInputLayout
的特殊功能的 none 将起作用。
如何解决这个问题比较难。我将从更改您的布局开始,改为使用此结构:
<FrameLayout>
<TextInputLayout>
<EditText/>
</TextInputLayout>
<Button/>
</FrameLayout>
这样你就可以有一个 "normal" TextInputLayout
层次结构 和 一个按钮来清除文本。您需要做更多的工作来定位按钮,使一切看起来自然,但这应该是一个可行的起点。
我最终在 XML 中使用以下内容解决了我的问题:
<android.support.design.widget.TextInputLayout
android:id="@+id/emailAddressTextInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<AutoCompleteTextView
android:id="@+id/emailAddress"
style="@style/body_text_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/prompt_email_address"
android:imeOptions="actionNext"
android:inputType="textEmailAddress"
android:maxLines="1"/>
<!--work around solution using negative marginTop-->
<Button
android:id="@+id/emailTextClearButton"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="end|center_vertical"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
//work around solution
android:layout_marginTop="-32dp"
android:background="@drawable/ic_clear_black_svg"/>
</android.support.design.widget.TextInputLayout>
WORKAROUND 是将我的 button
设置在我的 AutoCompleteTextView
下方,并使用 负 marginTop按钮,以便能够将其设置在需要设置的位置。
结果:
注意:我使用 RelativeLayout
作为 TextInputLayout