Android EditText

Filed Under: Android

In this tutorial, we’ll implement EditText in our Android Application. We’ll create EditText using XML as well as programmatically.

Android EditText

Android EditText is a subclass of TextView that allows user input and editing. It’s commonly used in login screens and forms.

EditText XML Definition

An EditText is defined in the XML in the following way.

<EditText
        android:id="@+id/inNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:hint="@string/enter_a_number_here"
        android:imeOptions="actionNext"
        android:inputType="number" />

EditText attributes

  1. android:id is used to set a unique identifier on the EditText
  2. layout_margin is used to set the margin outside the EditText view.
  3. hint is used to set the hint of the EditText.
  4. imeOptions is used to set the behaviour of the bottom rightmost keyboard button. It can be set to done, search, next etc. Setting it to next would take the cursor to the next EditText present in the screen.
  5. inputType is used to specify the input format allowed. By default it is text. email, number, numberDecimal etc can be set as per our needs.

Creating an EditText Programmatically

We have to create the EditText object and then add it to the screen layout.

val editText = EditText(this)
linearLayout.addView(editText)

EditText TextWatcher

TextWatcher is an interface, which listens to changes in the EditText before, after, and during an input is being typed.

It contains three functions that need to be overridden.

  1. afterTextChanged : it gets triggered immediately after something is typed
  2. beforeTextChanged : gets triggered before the next input.
  3. onTextChanged : it gets triggered during an input.

To set a TextWatcher on the EditText, we invoke the interface inside an addTextChangedListener function.

editText.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(s: Editable?) {
}

override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                toast(message = "Number is $s")
}

})

Kotlin Objects aren’t the same as the Java objects.

The onTextChanged() function differs from the afterTextChanged() in terms of the arguments.

Our example app would listen for changes in EditText input and update them in a TextView defined programmatically.

Android EditText Example Project Structure

android edittext project

1. Layout Code

The code for the activity_main.xml layout is given below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/inNumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:hint="@string/enter_a_number_here"
        android:imeOptions="actionNext"
        android:inputType="number" />

</LinearLayout>

2. Activity code

The code for the MainActivity.kt class is given below:

package net.androidly.androidlyedittext

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.content.ContextCompat
import android.text.Editable
import android.text.TextWatcher
import android.view.inputmethod.EditorInfo
import android.widget.*
import kotlinx.android.synthetic.main.activity_main.*
import android.widget.LinearLayout


class MainActivity : AppCompatActivity() {


    val txtAfter by lazy { TextView(this) }
    val txtOn by lazy { TextView(this) }
    val txtBefore by lazy { TextView(this) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val inNumber = findViewById(R.id.inNumber)

        inNumber.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                toast(message = "Number is $s")
            }

        })


        val editText = EditText(this)
        editText.apply {
            setText("Androidly EditText")
            hint = "Keep entering"
            val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            lp.setMargins(8, 8, 8, 8)
            layoutParams = lp
            imeOptions = EditorInfo.IME_ACTION_NEXT
            setTextColor(ContextCompat.getColor(this@MainActivity, android.R.color.holo_purple))
            smartTextWatcher(
                    on = { txtOn.apply { text = "onTextChanged: $it" } },
                    after = { txtAfter.apply { text = "smartTextWatcher: $it" } },
                    before = { txtBefore.apply { text = "beforeTextChanged: $it" } }
            )
        }


        linearLayout.addView(editText)

        val editText2 = EditText(this)
        editText2.apply {
            hint = "Enter something"
            val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            lp.setMargins(8, 8, 8, 8)
            layoutParams = lp
            setBackgroundColor(ContextCompat.getColor(this@MainActivity, android.R.color.holo_green_dark))
            imeOptions = EditorInfo.IME_ACTION_DONE
            smartTextWatcher(
                    on = { txtOn.apply { text = "onTextChanged: $it" } },
                    after = { txtAfter.apply { text = "smartTextWatcher: $it" } },
                    before = { txtBefore.apply { text = "beforeTextChanged: $it" } }
            )
        }

        linearLayout.addView(editText2)

        txtAfter.text = "AfterTextChanged :"
        txtAfter.setPadding(8, 8, 8, 8)
        linearLayout.addView(txtAfter)

        txtOn.text = "OnTextChanged :"
        txtOn.setPadding(8, 8, 8, 8)
        linearLayout.addView(txtOn)

        txtBefore.text = "BeforeTextChanged :"
        txtBefore.setPadding(8, 8, 8, 8)
        linearLayout.addView(txtBefore)
    }

    fun Context.toast(context: Context = applicationContext, message: String, duration: Int = Toast.LENGTH_SHORT) {
        Toast.makeText(context, message, duration).show()
    }

    fun EditText.smartTextWatcher(on: (String) -> Unit, after: (String) -> Unit, before: (String) -> Unit) {
        this.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
                after.invoke(s.toString())
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                before.invoke(s.toString())
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                on.invoke(s.toString())
            }
        })
    }
}

In the above code, we’ve created the TextViews programmatically and lazily using by lazy.

It means that the instance of TextView would be created only when it gets invoked in the class.

The findViewById<EditText> is used to get the EditText from the XML.

We display a toast when the text in the EditText is changed. The toast function is an extension function in Kotlin.

The apply lambda expression is used to set the attributes on the EditText without the need to invoke the instance every time.

To set the layout parameters programmatically, we do:

val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
lp.setMargins(8, 8, 8, 8)
layoutParams = lp

fun EditText.smartTextWatcher is an Extension function created to shorten the verbose code of the TextWatcher interface by using lambda expressions.

For each of its arguments, we update the respective text views inside the lambda expressions.

Output:

android edittext app output

You can download the AndroidlyEditText Project from the following link: AndroidlyEditText

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages