Skip to content

EditText with Toast in Android Kotlin: An Introduction

Read user input with EditText in Android Kotlin. Covers inputType, hint, maxLength, text.toString validation, Toast feedback, lifecycle tips.

· · 7 min read
Android emulator screen showing an EditText field with a hint and a Submit button below

Quick Take

EditText is the standard text input widget on Android. Pair it with a Button and a Toast and you have the smallest possible input form. This tutorial covers the XML attributes that matter, reading the value from Kotlin, validating it, and handling the lifecycle quirks.

Quick take: EditText reads single or multi-line text input from the user. Set inputType, hint, and maxLength in XML, then read editText.text.toString() in Kotlin to get the value. Toast.makeText(context, message, duration).show() is the simplest way to confirm a submission. For Material 3 apps, prefer TextInputEditText inside a TextInputLayout for floating labels and error states.

EditText is one of the oldest widgets in the Android framework, and it shows. The API is a little quirky (the text property returns an Editable, not a String), the validation patterns are mostly self-rolled, and Material Components add a wrapper layer on top to make it look modern. But it works on every Android version since the platform began, and every form, every login screen, every search box uses it.

I'll walk through the XML attributes that matter, the Kotlin code to read and validate input, and how to give feedback with a Toast. Along the way, a few lifecycle pitfalls that catch new devs.

How Do You Add an EditText in XML?

The minimum viable EditText looks like this:

<EditText
    android:id="@+id/name_input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Your name"
    android:inputType="textPersonName"
    android:maxLength="50" />

Four attributes matter:

  • android:id is required for view binding to give you a typed reference
  • android:hint shows placeholder text when the field is empty
  • android:inputType tells the keyboard what kind of input to expect (and sets autocorrect rules)
  • android:maxLength caps how many characters the user can type

Common inputType values worth knowing:

inputTypeKeyboardNotes
textDefaultPlain text with autocorrect
textPersonNameDefault, no autocorrectNames
textEmailAddressAdds @ and . on the keyboardEmail
textPasswordHides input as dotsPassword
textMultiLineAdds Enter key for new linesLong text
numberNumeric keypadWhole numbers
numberDecimalNumeric with .Decimals
phonePhone keypadPhone numbers

Pick the right one. Showing the wrong keyboard for the wrong field is a surprisingly common accessibility issue, especially on tablets where the user can't always switch easily.

Material 3 Approach

For Material 3 apps, wrap the EditText in a TextInputLayout and use TextInputEditText:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/name_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Your name"
    style="@style/Widget.Material3.TextInputLayout.OutlinedBox">

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/name_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:maxLength="50" />
</com.google.android.material.textfield.TextInputLayout>

This gives you a floating label, a built-in error display, and the outlined box style every modern Android app uses. The hint moves up to the top of the box on focus, which is the Material spec behaviour.

Two hands typing a message on an on-screen phone keyboard
Photo by freestocks on Unsplash

How Do You Read EditText Input in Kotlin?

Assuming view binding is enabled, reading the value is one line:

val name: String = binding.nameInput.text.toString()

The .text property returns an Editable, which is essentially a mutable string. Converting to String with .toString() gives you a stable, immutable value to work with. Add .trim() to drop accidental leading/trailing whitespace, which copy-paste often introduces:

val name: String = binding.nameInput.text.toString().trim()

That one line covers about 95% of cases. The remaining 5% involves real-time validation as the user types, which uses a TextWatcher:

binding.nameInput.doAfterTextChanged { editable ->
    val current = editable.toString()
    binding.submitButton.isEnabled = current.length >= 3
}

doAfterTextChanged is a Kotlin extension on EditText that wraps the older TextWatcher interface. Per the Android KTX docs, it's the recommended approach for new Kotlin code. The lambda fires after each character change, so you can enable or disable the submit button based on current input.

How Do You Validate Input Before Showing a Toast?

Pair a button with the EditText, validate inside the click handler, and show different Toast messages for success and failure:

binding.submitButton.setOnClickListener {
    val name = binding.nameInput.text.toString().trim()

    when {
        name.isEmpty() -> {
            Toast.makeText(this, "Please enter a name", Toast.LENGTH_SHORT).show()
        }
        name.length < 2 -> {
            Toast.makeText(this, "Name must be at least 2 characters", Toast.LENGTH_SHORT).show()
        }
        else -> {
            Toast.makeText(this, "Hello, $name", Toast.LENGTH_LONG).show()
            binding.nameInput.text?.clear()
        }
    }
}

A few things worth noting:

  • name.isEmpty() is the Kotlin equivalent of name.length == 0, but more readable
  • The when block reads top-to-bottom, the first matching branch wins
  • binding.nameInput.text?.clear() empties the field after success, the ? is because text is technically nullable

For Material 3 with TextInputLayout, you can attach the error to the field itself instead of using Toast:

if (name.isEmpty()) {
    binding.nameLayout.error = "Please enter a name"
} else {
    binding.nameLayout.error = null
    Toast.makeText(this, "Hello, $name", Toast.LENGTH_LONG).show()
}

}


The error appears in red below the field, the box outline turns red, and the floating label switches colour. Much better UX than a Toast for validation errors, save Toasts for confirmations and transient feedback.

## How Do You Show a Toast?

Three parameters, then `.show()`:

```kotlin
Toast.makeText(context, message, duration).show()
  • context is this in an activity or requireContext() in a fragment
  • message is a String or a string resource ID
  • duration is Toast.LENGTH_SHORT (about 2 seconds) or Toast.LENGTH_LONG (about 3.5 seconds)

Calling .makeText without .show() is the most common Toast mistake. The code compiles, runs, and silently does nothing. I've seen this in production code at three different jobs.

A few more Toast facts that come up:

  • Two Toasts in a row get queued, the second appears after the first fades out
  • You can hold a reference to a Toast and call .cancel() to dismiss early
  • On Android 11+, the position is fixed near the bottom, setGravity is ignored for non-system apps for accessibility reasons

If you need more than Toast offers (custom layouts, actions, custom durations), use Snackbar from Material Components instead.

A hand holding a smartphone that displays an app screen with a small popup notification
Photo by freestocks on Unsplash

What About the Activity Lifecycle?

EditText state survives rotation automatically, as long as you set android:id. The framework calls onSaveInstanceState before destroying the activity and restores the text in the recreated activity's onCreate. You don't write any code for this.

What doesn't survive automatically:

  • Custom data you derived from the input (parsed numbers, validation state)
  • Cursor position if you're doing tricky text manipulation
  • Focus, if you've focus-shifted programmatically

For custom state, override onSaveInstanceState and onRestoreInstanceState:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean("submitted", hasSubmitted)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    hasSubmitted = savedInstanceState?.getBoolean("submitted") ?: false
}

In practice, I push this kind of state into a ViewModel and let the EditText handle its own text restoration. Less ceremony, better separation. A ViewModel is the right tool for state that needs to survive rotation but doesn't belong in the view itself.

What Are the Common Pitfalls?

A short list from real projects:

  1. Wrong inputType. A phone number field with default text input is a usability disaster on every device. Always pick the right one.
  2. Forgetting .trim(). Pasted email addresses bring leading or trailing spaces. Validation fails for non-obvious reasons.
  3. Reading the value too early. If you read binding.nameInput.text.toString() in onCreate before the user types anything, you get an empty string. Read it in the click handler.
  4. Skipping accessibility. Set android:contentDescription or use the floating label so screen readers announce the field properly. Honestly, this is the one most developers (me included) forget on first pass.

Get those four right and EditText becomes a non-issue. The harder work is what you do with the input after, which usually means a ViewModel, a repository, and eventually a network call. That's a whole different post.

Frequently Asked Questions

What's the difference between EditText and TextInputEditText?
TextInputEditText is the Material Components version, designed to live inside a TextInputLayout for floating labels and error display. EditText is the original framework widget. For new apps using Material 3, prefer TextInputEditText, you get the floating label, the helper text slot, and the error display for free.
How do I read text from an EditText in Kotlin?
Call editText.text.toString(). The text property returns an Editable, which is mutable, so converting it to a plain String is the safe move before validation. binding.nameInput.text.toString().trim() is the typical one-liner, the trim handles whitespace pasted from elsewhere.
What does inputType do in EditText?
inputType tells the keyboard what kind of input to expect, which changes the on-screen keyboard layout and the autocorrect behaviour. textEmailAddress shows the @ key, number gives a numeric keypad, textPassword masks the characters. Pick the right one for accessibility and the right experience on every device.
Why does my EditText keep its value after rotation?
Android saves and restores the EditText state automatically as long as the view has an android:id. After a rotation, the activity is destroyed and recreated, but the framework calls onSaveInstanceState before destruction and restores the EditText content in onCreate. If you're losing state, double-check the id is set on every EditText.
Can a Toast show across multiple activities?
Yes. Toasts are bound to the application, not the activity that triggered them. If you call Toast.makeText(applicationContext, ...).show() before navigating, the Toast keeps showing on the next screen. Useful for confirmation messages that survive a transition.