Android EditText with different floating label and placeholder
Asked Answered
S

8

26

How can i create an editText that looks like this?

Edit Text with placeholder and label

Spearman answered 24/5, 2017 at 16:41 Comment(0)
S
28

You can do this using TextInputLayout and EditText.

Here is your 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. Add attribute android:hint="Label" to TextInputLayout to show its hints Label always.

2. Programmatically set EditText hints Placeholder only when EditText get focused.

Add below lines in your 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("");
            }
        }
    });

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

OUTPUT:

enter image description here

Hope this will help~

Selry answered 24/5, 2017 at 18:19 Comment(5)
Is there a way to keep the label and placeholder like the screenshot in unfocused state?Spearman
Yes its possible. Use android:focusableInTouchMode="true" to parent/container layout.Selry
Floating label and hint do work, but I need to tap twice on the field in order to show up the keyboard. Any suggestions?Wadding
@andreasimeoni - use focusableInTouchMode="false" to prevent the double-tap issue. When you set focusableInTouchMode totrue you're telling the View that it should only focus the view on first tap, without performing the action (showing the keyboard in this case), resulting in the user needing to tap the View twice to show the keyboard. A different example of this would be setting focusableInTouchMode to true on a Button doing so would require 2 taps for onClickEvent to be called - since the first tap only focuses views when focusableInTouchMode="true".Bogus
@andreasimeoni - I usually solve these "automatic focus" issues that occur by focusing the layouts parent/root view when created or whenever I need to remove focus from a view in a layout. You'll need to give the parent/root Layout an android:id and set focusable="true" on it, NOT focusableInTouchMode on the parent/root layout.Bogus
P
14

With the Material Components Library you can use:

  • app:placeholderText: to add a placeholder text in the EditText
  • android:hint: to add a floating label

They can work together:

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

enter image description here

Note: it requires at least the version 1.2.0-alpha03.

Prophet answered 27/7, 2020 at 21:54 Comment(1)
note that this will only work when the edit text is in focus. when not in focus, the hint ("label") will show instead of the placeholderOutfox
F
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>

Notice that android:hint="Placeholder" from TextInputEditText is visible at the same time with android:hint="Label" from TextInputLayout when view is not focused. You could do some extra checking in your java code to show and hide that label. Or just leave android:hint="Placeholder" from TextInputLayout.

To change color, you need to set a theme using android:theme="@style/TextLabel for TextInputLayout and there set your color accent.

<style name="TextLabel" parent="TextAppearance.AppCompat.Light">
   <item name="colorAccent">@color/yourColor</item>
</style>
Forensic answered 24/5, 2017 at 16:58 Comment(0)
D
4

As i know, best possible way how to solve this task with 2 different texts (placeholder and hint) together is to use the code below:

 <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>
Deferent answered 20/9, 2021 at 21:37 Comment(0)
S
2

You can use following code (in kotlin). It will show placeholder after 200 ms delay (to avoid overlapping hint and placeholder).

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 = ""
            }
        }
    }
}

and then in layout xml class:

    <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>
Spindrift answered 13/11, 2017 at 14:3 Comment(0)
T
2

GIVEN: A TextInputEditText nested in TextInputLayout!

TL;DR!: Use this Kotlin Extension Function

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 = ""
        }
    }
}

What's the problem and how does it solve it?

The Problem is that the hint of the EditText gets overlapped if there is a hint in the TextInputLayout. Which one to show in this case? Good question: We only want the EditText's hint to be displayed when it's focused/the cursor is inside but the TextInputLayout hint to be displayed always.

⮑ So we only set the hint for the EditText when it has the focus and remove it once it loses focus 🐙

Tearing answered 17/1, 2019 at 12:24 Comment(0)
C
0

You can use below layout xml file as below.

<?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>
Conservation answered 24/5, 2017 at 16:46 Comment(0)
S
0

If you use textinputlayout then on focus of edittext, you didn't get any placeholder.

Layout:

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

You have to set a focus change listener of the edittext.

Java:

usernameTxt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            usernameTxt.setHint("Label");
        } else {
            usernameTxt.setHint("Placeholder");
        }
    }
});
Spermogonium answered 24/5, 2017 at 17:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.