A password field normally masks its characters. A show/hide control lets the user temporarily reveal the entered password, check it for typing mistakes, and hide it again without clearing the field.

Show and Hide Password in Android EditText Using Kotlin

In this Android Tutorial, we demonstrate how to show or hide a password in an Android EditText. The page includes the original button-based example, a current Kotlin example using View Binding, and the Material Components password-toggle option.

Following is a quick glimpse of the password visibility behavior.

Kotlin Android EditText - Show/Hide Password

How Android EditText Password Visibility Works

  1. Set the password field’s input type to textPassword so Android masks the entered characters initially.
  2. To reveal the password, set transformationMethod to HideReturnsTransformationMethod.getInstance().
  3. To mask the password again, set transformationMethod to PasswordTransformationMethod.getInstance().
  4. After changing the transformation method, restore the cursor to the end with setSelection(text.length).
  5. Update the button text, icon, and content description so the control accurately describes its next action.

The transformation method changes only how the text is displayed. It does not replace, remove, or encrypt the actual text stored in the EditText.

Original Button-Based EditText Password Toggle Example

Create an Android Project and replace the activity_main.xml and MainActivity.kt with the following code.

activity_main.xml

</>
Copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <LinearLayout
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_marginTop="100sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <EditText
        android:id="@+id/pwd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="200sp"
        android:hint="Password"
        android:inputType="textPassword" />
    <Button
        android:id="@+id/showHideBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show"/>
    </LinearLayout>

</LinearLayout>

MainActivity.kt

</>
Copy
package com.tutorialkart.showhidepassword

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;

class MainActivity : AppCompatActivity() {

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

        showHideBtn.setOnClickListener {
            if(showHideBtn.text.toString().equals("Show")){
                pwd.transformationMethod = HideReturnsTransformationMethod.getInstance()
                showHideBtn.text = "Hide"
            } else{
                pwd.transformationMethod = PasswordTransformationMethod.getInstance()
                showHideBtn.text = "Show"
            }
        }
    }
}

The original example uses Kotlin synthetic view references. Kotlin Android Extensions synthetic view binding is no longer supported in current Android projects. For new projects, use View Binding or findViewById. The updated example below also keeps the cursor at the end after each visibility change.

Current Kotlin EditText Password Toggle with View Binding

Enable View Binding in the application module’s build.gradle.kts file.

</>
Copy
android {
    buildFeatures {
        viewBinding = true
    }
}

Use a password EditText and a button in activity_main.xml.

</>
Copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="24dp">

    <EditText
        android:id="@+id/passwordEditText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:autofillHints="password"
        android:hint="Password"
        android:imeOptions="actionDone"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/passwordToggleButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show" />

</LinearLayout>

Inflate the generated binding class and switch the transformation method when the user taps the button.

</>
Copy
package com.tutorialkart.showhidepassword

import android.os.Bundle
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import androidx.appcompat.app.AppCompatActivity
import com.tutorialkart.showhidepassword.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private var isPasswordVisible = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.passwordToggleButton.setOnClickListener {
            isPasswordVisible = !isPasswordVisible

            binding.passwordEditText.transformationMethod =
                if (isPasswordVisible) {
                    HideReturnsTransformationMethod.getInstance()
                } else {
                    PasswordTransformationMethod.getInstance()
                }

            binding.passwordToggleButton.text =
                if (isPasswordVisible) "Hide" else "Show"

            binding.passwordToggleButton.contentDescription =
                if (isPasswordVisible) "Hide password" else "Show password"

            binding.passwordEditText.setSelection(
                binding.passwordEditText.text.length
            )
        }
    }
}

Material TextInputLayout Password Toggle

When the project uses Material Components, TextInputLayout can provide the visibility icon without a separate button. Set app:endIconMode="password_toggle" and place a password-compatible TextInputEditText inside it.

</>
Copy
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Password"
    app:endIconMode="password_toggle">

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/passwordEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:autofillHints="password"
        android:imeOptions="actionDone"
        android:inputType="textPassword" />

</com.google.android.material.textfield.TextInputLayout>

This is usually the simpler XML approach because the Material component manages the end icon and password transformation behavior. The layout must declare the Material namespace, such as xmlns:app="http://schemas.android.com/apk/res-auto", on its root element.

Keep the Cursor Position When Showing or Hiding the Password

Changing an EditText transformation method can move the cursor. Restore it after the change so the user can continue typing at the same logical position.

</>
Copy
val cursorPosition = passwordEditText.selectionStart

passwordEditText.transformationMethod =
    if (showPassword) {
        HideReturnsTransformationMethod.getInstance()
    } else {
        PasswordTransformationMethod.getInstance()
    }

passwordEditText.setSelection(
    cursorPosition.coerceIn(0, passwordEditText.text.length)
)

For a basic sign-in form where the cursor normally remains at the end, setSelection(passwordEditText.text.length) is sufficient.

Common Android Password Toggle Problems

Password remains visible after tapping Hide

Use PasswordTransformationMethod.getInstance() for the hidden state. HideReturnsTransformationMethod reveals the ordinary characters; its class name refers to hiding carriage-return characters, not hiding the password.

Show and Hide button state becomes incorrect

Track visibility with a Boolean variable instead of relying only on the button’s displayed text. This avoids logic errors after localization, state restoration, or programmatic text changes.

Cursor jumps to the beginning of the EditText

Call setSelection() after assigning the new transformation method. Preserve selectionStart when editing in the middle of the password.

Material password icon does not appear

Confirm that the app uses a Material Components theme, the Material library is included, the child field uses a password input type, and app:endIconMode="password_toggle" is set on TextInputLayout.

Password Field Usability and Security Notes

  • Start with the password hidden and reveal it only after a deliberate user action.
  • Do not log the password or include it in analytics, crash messages, or debug output.
  • Use android:autofillHints="password" so compatible password managers can identify the field.
  • Give an icon-only visibility control a meaningful content description such as “Show password” or “Hide password”.
  • A visibility toggle improves input checking but does not encrypt or securely store the password. Apply normal transport and credential-storage protections separately.

Android EditText Show/Hide Password FAQs

Which transformation method hides an Android password?

PasswordTransformationMethod.getInstance() masks the password characters. Assign it to the EditText.transformationMethod property when the field should return to its hidden state.

Which transformation method shows the password text?

HideReturnsTransformationMethod.getInstance() displays the entered characters normally. After assigning it, restore the selection so the cursor does not unexpectedly move.

Can Android show a password icon without Kotlin toggle code?

Yes. A Material TextInputLayout with app:endIconMode="password_toggle" supplies the visibility icon and manages the transformation behavior for its password field.

Why does an old Kotlin password-toggle example not compile?

Older examples may import kotlinx.android.synthetic or use the old support library package. Current projects should use AndroidX and access views through View Binding or findViewById.

Does showing a password change the EditText value?

No. The transformation method changes the visual representation of the text. The underlying editable value remains the same.

Editorial QA Checklist for the Android Password Toggle Example

  • Verify that textPassword masks the field when the screen first opens.
  • Verify that Show uses HideReturnsTransformationMethod and Hide uses PasswordTransformationMethod.
  • Verify that the password text is preserved through repeated visibility changes.
  • Verify that the cursor remains at the expected position after each toggle.
  • Verify that button text, icon state, and content description match the next available action.
  • Verify that the current example uses AndroidX and View Binding rather than Kotlin synthetic references.
  • Verify the Material example under the app’s active Material theme.