0

I am using a checkbox to toggle password visibility in edit text. Basically, when I check/uncheck the checkbox, the cursor of the edit text shifts to the initial position of the character in the password text. It should not change the cursor position in edit text when the checkbox is checked or unchecked.

Please anyone can suggest why the cursor position changes? and how I can fix that?

login_layout

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">


        <EditText
            android:id="@+id/etUsername"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:autofillHints="name"
            android:hint="Username"
            android:imeOptions="actionNext"
            android:inputType="text"
            android:maxLines="1"
            android:padding="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/etPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:autofillHints="password"
            android:hint="Password"
            android:imeOptions="actionDone"
            android:inputType="textPassword"
            android:maxLines="1"
            android:padding="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/etUsername" />

        <CheckBox
            android:id="@+id/imgTogglePassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="-5dp"
            android:layout_marginEnd="-5dp"
            android:button="@drawable/btn_toggle_password"
            android:padding="16dp"
            app:layout_constraintBottom_toBottomOf="@id/etPassword"
            app:layout_constraintEnd_toEndOf="@id/etPassword"
            app:layout_constraintTop_toTopOf="@id/etPassword" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

LoginActivity

import android.os.Bundle
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.testapp.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        initUI()
    }

    private fun initUI() {
        binding.imgTogglePassword.setOnCheckedChangeListener { _, isChecked ->
            // checkbox status is changed from uncheck to checked.
            if (!isChecked) {
                // hide password
                binding.etPassword.transformationMethod = PasswordTransformationMethod.getInstance()
            } else {
                // show password
                binding.etPassword.transformationMethod = HideReturnsTransformationMethod.getInstance()
            }
        }
    }


}

Login Page

Issue

Kiran
  • 31
  • 7
  • Instead of using checkbox for password toggle , try using [TextInputLayout](https://stackoverflow.com/questions/39867669/show-password-icon-in-textinputlayout-touching-the-base-line) to make edit text with password toggle icon. – Nitish Nov 15 '21 at 07:06
  • @Nitish, I don`t need the hint to slide up when one starts to type their password. I have certain design requirements without text input layout. – Kiran Nov 15 '21 at 07:08
  • You can disable hint slide up in TextInputLayout using `app:hintAnimationEnabled` . And above design can be achieved easily , example shared in first comment. If you still want to use checkbox , I believe `transformationMethod` is resetting the cursor position on each toggle, try setting [cursor at end](https://stackoverflow.com/questions/6217378/place-cursor-at-the-end-of-text-in-edittext) after transformationMethod – Nitish Nov 15 '21 at 07:13

2 Answers2

0

You just need to use this line : binding.etPassword.setSelection(binding.etPassword.text.length) as the below code.

 import android.os.Bundle
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.testapp.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        initUI()
    }

    private fun initUI() {
        binding.imgTogglePassword.setOnCheckedChangeListener { _, isChecked ->
            // checkbox status is changed from uncheck to checked.
            if (!isChecked) {
                // hide password
                binding.etPassword.transformationMethod = PasswordTransformationMethod.getInstance()
            } else {
                // show password
                binding.etPassword.transformationMethod = HideReturnsTransformationMethod.getInstance()
            }

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


}

Kiran
  • 31
  • 7
0

CheckBox is not the common way to show/hide password.

Try endIconDrawable:

<com.google.android.material.textfield.TextInputLayout
    ...
    app:endIconDrawable="@drawable/selector_button_eye"
    app:endIconCheckable="true"
    app:endIconTint="@color/colorEyeButtonTint">

        <com.google.android.material.textfield.TextInputEditText
            ...
            android:inputType="textPassword" />

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

I' m not sure about the "endIconXXX" attributes because I only used the deprecated passwordToggleDrawable before. But they are similar.

Krahmal
  • 195
  • 13
  • Thanks for the answer. But the design layout does not need a text input layout so I had to figure out a different way. – Kiran Jan 31 '22 at 05:32
  • Glad you got what you wanted, but I still want to suggest you to use style inherits from ```Widget.MaterialComponents.TextInputLayout.FilledBox``` to achieve the same effect :P – Krahmal Feb 07 '22 at 01:26