Introduction
The EditText
is the standard text entry widget in Android apps. If the user needs to enter text into an app, this is the primary way for them to do that.
An EditText is added to a layout with all default behaviors with the following XML:
<EditText android:id="@+id/etTitle" android:layout_height="wrap_content" android:layout_width="match_parent"/>
Note that an EditText
is simply a thin extension of the TextView
and inherits all of the same properties.
To retrieve the value of an EditText
control from within your Activity
, you can use the getText()
method of the EditText
class. For example, the following code retrieves a handle to the EditText
control defined as etTitle
:
EditText etTitle = (EditText) findViewById(R.id.etTitle); String title = etTitle.getText().toString();
By default, any text contents within an EditText
control is displayed as plain text. By setting inputType
, we can facilitate input of different types of information, like phone numbers and passwords:
<EditText ... android:inputType="phone"> <EditText>
Most common input types include:
Type | Description |
---|---|
textUri | Text that will be used as a URI |
textEmailAddress | Text that will be used as an e-mail address |
textPersonName | Text that is the name of a person |
textPassword | Text that is a password that should be obscured |
textVisiblePassword | Text, next button, and no microphone input |
number | A numeric only field |
phone | For entering a phone number |
date | For entering a date |
time | For entering a time |
textMultiLine | Allow multiple lines of text in the field |
You can set multiple inputType
attributes if needed (separated by '|')
<EditText android:inputType="textCapSentences|textMultiline"/>
You can see a list of all available input types here.
Customization
We might want to limit the entry to a single-line of text (avoid newlines):
<EditText android:maxLines="1" android:lines="1"/>
You can limit the characters that can be entered into a field using the digits attribute:
<EditText android:inputType="number" android:digits="01"/>
This would restrict the digits entered to just "0" and "1".
We might want to limit the total number of characters with:
<EditText android:maxLength="5"/>
Using these properties we can define the expected input behavior for text fields.
Displaying floating label
Traditionally, the EditText
hides the hint
message after the user starts typing. In addition, any validation error messages had to be managed manually by the developer.
Starting with Android M and the design support library, the TextInputLayout
can be used to setup a floating label to display hints and error messages. First, wrap the EditText
in a TextInputLayout:
<android.support.design.widget.TextInputLayout android:id="@+id/tilTitle" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/etTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="Title" /> </android.support.design.widget.TextInputLayout>
We can also use the TextInputLayout
to display error messages using the setError
and setErrorEnabled
properties in the activity at runtime:
final TextInputLayout tilTitle = (TextInputLayout) findViewById(R.id.tilTitle); tilTitle.getEditText().addTextChangedListener(new TextWatcher() { // ... @Override public void onTextChanged(CharSequence text, int start, int count, int after) { if (text.length() > 0 && text.length() <= 4) { tilTitle.setError(getString(R.string.title_required)); tilTitle.setErrorEnabled(true); } else { tilTitle.setErrorEnabled(false); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void afterTextChanged(Editable s) {} });
Here we use the addTextChangedListener
to watch as the value changes to determine when to display the error message or revert to the hint.
Listening for EditText input
There are a few common listeners for input fields:
addTextChangedListener
- fires each time the text in the field is being changed.setOnEditorActionListener
- fires when an "action" button on the soft keyboard is pressed.TextChangedListener
If you want to handle an event as the text in the view is being changed, you only need to look as far as the addTextChangedListener
method on an EditText
:
EditText etTitle = (EditText) findViewById(R.id.etTitle); etTitle.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // Fires right as the text is being changed (even supplies the range of text) } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // Fires right before text is changing } @Override public void afterTextChanged(Editable s) { // Fires right after the text has changed tvTitle.setText(s.toString()); } });
This is great for any time you want to have the UI update as the user enters text.
OnEditorActionListener
Another case is when you want an action to occur once the user has finished typing text with the Soft Keyboard. Keep in mind that this is especially useful when you can see the virtual keyboard which is disabled by default in the emulator but can be enabled as explained in this graphic.
First, we need to setup an "action" button for our text field. To setup an "action button" such as a Done button on the Soft Keyboard, simply configure your EditText
with the following properties:
<EditText android:id="@+id/etTitle" android:inputType="text" android:singleLine="true" android:imeOptions="actionDone" android:layout_width="match_parent" android:layout_height="wrap_content"> <requestFocus /> </EditText>
In particular, singleLine
and imeOptions
are required for the Done button to display. Now, we can hook into a editor listener for when the done button is pressed with:
etTitle.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { String text = v.getText().toString(); Toast.makeText(activity, text, Toast.LENGTH_SHORT).show(); // hide keyboard //InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); //inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); return true; } return false; } });
This is often great whenever a user needs to type text and then explicitly have an action performed when they are finished. There are many imeOptions for different situations.
Adding character counting
TextInputLayout
since the announcement of support design library v23.1 also can expose a character counter for an EditText
defined within it. The counter will be rendered below the EditText
and can change colors of both the line and character counter if the maximum number of characters has been exceeded:
The TextInputLayout
simply needs to define app:counterEnabled
and app:CounterMaxLength
in the XML attributes. These settings can also be defined dynamically through setCounterEnabled()
and setCounterMaxLength()
:
<android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:counterEnabled="true" app:counterMaxLength="10" app:counterTextAppearance="@style/counterText" app:counterOverflowTextAppearance="@style/counterOverride"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="Title" /> </android.support.design.widget.TextInputLayout>
The counter text and overflow text can also have their own text styles by defining app:counterTextAppearance
and app:counterOverflowTextAppearance
. We can use textColor
, textSize
, and fontFamily
to help change the color, size, or font. Add following snippets to res/values/styles.xml.
<style name="counterText"> <item name="android:textColor">#aa5353cc</item> </style> <style name="counterOverride"> <item name="android:textColor">#ff0000</item> </style>
Shake EditText on error
The animation specification is created in XML files in the anim directory. In this example, we want the text entry field to be able to shake either left to right. So, we create an animation, res/anim/shake.xml:
<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="1000" android:interpolator="@anim/cycler"/>
The interpolator
- the function that drives the animation. It's contained in another file, res/anim/cycler.xml, shown here:
<?xml version="1.0"?> <cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="2"/>
To apply the animations to EditText
component, you need a reference to it. You can, of course, use the common findViewById(R.id.*)
. You can also use the Activity
method getCurrentFocus()
if you are dealing with the current input (focused) View
component; this avoids coupling to the name of a particular component, if you know that your animation will always apply to the current input object.
etTitle.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.shake));
The shaking effect is convenient for drawing the user’s attention to an input that is incorrect
Stylization
EditText
control can be styled using styles.xml file to make it more attractive and stylish.
Add a style element as below in your res>values>styles.xml :
<style name="MyEditTextStyle" parent="android:Widget.EditText"> <item name="android:textColor">#400000</item> <item name="android:textStyle">bold</item> <item name="android:padding">10dp</item> <item name="android:typeface">monospace</item> <item name="android:background">@android:drawable/editbox_background_normal</item> <item name="android:textSize">20sp</item> </style>
And supply this style name to your EditText
control in design file:
<EditText android:id="@+id/etTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:hint="Enter your title" android:inputType="text" android:textColor="#000" style="@style/MyEditTextStyle"/>
How to disable drag event on EditText
editText.setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { return true; } });
Returns true
if the drag event was handled successfully, or false
if the drag event was not handled. Note that false will trigger the View
to call its onDragEvent()
handler.
EditText example in Kotlin
Set some text to the EditText
edit_text.setText("Hello World")
Get the EditText
text on button click event
val inputtedText = edit_text.text
Set a text change listener for edit text object
edit_text.addTextChangedListener(object: TextWatcher{ override fun afterTextChanged(p0: Editable?) { // Do something after text changed } override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { // Do something before text changed on EditText } override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { // Do something on text changed in EditText // Display the EditText change text on TextView real time text_view.text = edit_text.text } })