Android EditText具有不同的浮动标签和占位符

26

我该如何创建一个类似这样的文本输入框?

带占位符和标签的文本输入框

8个回答

26

您可以使用TextInputLayoutEditText来实现这一点。

这是您的XML代码:

<android.support.design.widget.TextInputLayout
    android:id="@+id/text_input_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Label">

    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />

</android.support.design.widget.TextInputLayout>

1. 将属性android:hint="Label"添加到TextInputLayout中,以始终显示其提示Label

2.EditText被聚焦时,通过编程方式设置EditText提示Placeholder

在您的Activity中添加以下行:

    .........
    .................

    final EditText editText = (EditText) findViewById(R.id.edit_text);

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            if (hasFocus) {
                editText.setHint("Placeholder");
            } else {
                editText.setHint("");
            }
        }
    });

    .........
    ..................

输出:

enter image description here

希望这可以帮到您~


2
有没有办法在未聚焦状态下保留标签和占位符,就像屏幕截图中的那样? - Mohammad Shabaz Moosa
1
是的,这是可能的。在父/容器布局中使用android:focusableInTouchMode="true" - Ferdous Ahamed
2
浮动标签和提示确实起作用,但我需要在字段上点击两次才能显示键盘。有什么建议吗? - andrea simeoni
@andreasimeoni - 使用 focusableInTouchMode="false" 来避免双击问题。当你将 focusableInTouchMode 设置为 true 时,你告诉 View 它应该 在第一次点击时聚焦视图,而不执行操作(在这种情况下显示键盘),导致用户需要点击两次 View 才能显示键盘。另一个例子是在 Button 上设置 focusableInTouchModetrue,这样做需要两次点击才能调用 onClickEvent - 因为第一次点击仅在 focusableInTouchMode="true" 时聚焦视图。 - Sakiboy
我通常通过在布局创建时或需要从布局中的视图中移除焦点时,将焦点集中于布局的父/根视图来解决自动对焦问题。您需要给父/根布局设置 android:id 并在其上设置 focusable="true",而不是在父/根布局上设置 focusableInTouchMode - Sakiboy

13

使用 Material Components 库,您可以使用以下内容:

  • app:placeholderText:在 EditText 中添加占位符文本
  • android:hint:添加浮动标签

它们可以一起使用:

<com.google.android.material.textfield.TextInputLayout
        android:hint="Label"
        app:placeholderText="Placeholder Text"

输入图像描述

注意:它需要至少1.2.0-alpha03版本。


2
请注意,此功能仅在编辑文本处于焦点状态时才有效。当不处于焦点状态时,提示(“标签”)将显示在占位符之前。 - or_dvir

8
<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Label">

    <android.support.design.widget.TextInputEditText
        android:hint="Placeholder"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress" />

</android.support.design.widget.TextInputLayout>

请注意,当视图没有焦点时,来自TextInputEditText的android:hint="Placeholder"与来自TextInputLayout的android:hint="Label"同时可见。您可以在Java代码中进行额外检查以显示和隐藏该标签。或者只需保留来自TextInputLayout的android:hint="Placeholder"。
要更改颜色,您需要为TextInputLayout设置主题,使用android:theme="@style/TextLabel,并在那里设置您的颜色强调。
<style name="TextLabel" parent="TextAppearance.AppCompat.Light">
   <item name="colorAccent">@color/yourColor</item>
</style>

4

据我所知,将2个不同的文本(占位符和提示)放在一起解决此任务的最佳方式是使用以下代码:

 <com.google.android.material.textfield.TextInputLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:hintEnabled="true" // enable hint/placeholder on EditText
            android:hint="@string/title_of_input" // title shown above EditText
            app:expandedHintEnabled="false" // disable move placeholder to hint place
            app:placeholderText="@string/placeholder_for_edittetx" // placeholder shown in EditText when no text is filled by user
>

            <com.google.android.material.textfield.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </com.google.android.material.textfield.TextInputLayout>

2
您可以使用以下代码(在Kotlin中)。 它将在200毫秒延迟后显示占位符(以避免提示和占位符重叠)。
class PlaceholderEditText : TextInputEditText {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    private val placeholder = hint

    init {
        hint = ""
        onFocusChangeListener = OnFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                postDelayed({ hint = placeholder }, 200)
            } else {
                hint = ""
            }
        }
    }
}

然后在布局xml类中:

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="ALWAYS VISIBLE LABEL">

        <com.myapp.widget.PlaceholderEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="DISAPPEARING PLACEHOLDER" />

    </android.support.design.widget.TextInputLayout>

2

给定:一个嵌套在TextInputLayout中的TextInputEditText

简而言之:使用这个Kotlin扩展函数。

fun EditText.setHintAndLabel(
        textInputLayout: TextInputLayout,
        label: String?, // hint in the TextInputLayout
        hint: String? // hint in the EditText
) {
    this.hint = ""
    textInputLayout.hint = label

    this.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
        if (hasFocus) {
            this.hint = hint ?: ""
        } else {
            this.hint = ""
        }
    }
}

问题是什么,它如何解决?

问题在于,如果TextInputLayout中有提示,则EditText的提示会重叠。在这种情况下显示哪个提示呢?好问题:我们只想在EditText获得焦点/光标在内部时显示其提示,但是TextInputLayout提示始终应该显示。

⮑ 因此,我们只在EditText获得焦点时设置提示,并在失去焦点时将其删除。


0
您可以像下面这样使用以下布局xml文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:text="Label"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/textView2"
    android:textColor="@color/wallet_holo_blue_light" />
<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textPersonName"
    android:text="Name"
    android:ems="10"
    android:id="@+id/editText2"
    android:hint="Placeholder" />
    </LinearLayout>

0
如果您使用textinputlayout,那么在edittext获得焦点时,您将无法获取任何占位符。
布局:
<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/username_txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.design.widget.TextInputLayout>

你需要为EditText设置一个焦点变化监听器。

Java:

usernameTxt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            usernameTxt.setHint("Label");
        } else {
            usernameTxt.setHint("Placeholder");
        }
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接