Calling setSingleLine on an EditText with inputType=textPassword make characters visible

275 Views Asked by At

I put an EditText with inputType="textPassword" in my activity's XML

<EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Enter Password"
        android:inputType="textPassword"
        android:padding="16dp"
        android:id="@+id/passwordInput"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

Till now there is not any problem and I see circles intead of real password characters:

enter image description here

The interesting part is here. Now if I call setSingleLine() on the EditText in the Activity:

class MainActivity : AppCompatActivity() {

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

        passwordInput.setSingleLine()
    }
}

will see that the password characters is surprisingly visible!

enter image description here

Another interesting thing is that this issue will not happen if I put android:singleLine="true" in XML of the EditText.

Note: I know that setting setSingleLine on a password field is useless, but I'm curious why calling this function has such side effect.

3

There are 3 best solutions below

0
On BEST ANSWER

I think it is because when you call setSingleLine, textview will change it transformation method from PasswordTransformationMethod to SingleLineTransformationMethod. there is only one transformation method accepted at the time in EditText (which is child of TextView)

you can check the source code here: setSingleLine() https://android.googlesource.com/platform/frameworks/base/+/jb-mr0-release/core/java/android/widget/TextView.java#6727

follow through the code fill call function setTransformationMethod

https://android.googlesource.com/platform/frameworks/base/+/jb-mr0-release/core/java/android/widget/TextView.java#1461

1
On

Try to set it inside XML:

android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"

I can't tell you why setting it programaticaly lead to this strange behavior because I usually do this inside XML and I'm doing this in code just to manipulate Views.

2
On
  • If you want to hide the password, you will:

    yourTextView.setTransformationMethod(new PasswordTransformationMethod());

  • If you want to show the password, you will:

    yourTextView.setTransformationMethod(new DoNothingTransformation()), or setTransformationMethod(null)

  • Method setTransformationMethod is show/hide text enter image description here

  • Now, you can check the code of class TextView, Because of EditText extended from TextView. You will see in the function setSingleLine(), It's call function applySingleLine(singleLine, true, true), This function will set again setTransformationMethod(SingleLineTransformationMethod.getInstance()); This is change your Transformation(show/hide text of EditText):

    private void applySingleLine(boolean singleLine, boolean applyTransformation,
        boolean changeMaxLines) {
    mSingleLine = singleLine;
    if (singleLine) {
        setLines(1);
        setHorizontallyScrolling(true);
        // change Transformation
        if (applyTransformation) {
            setTransformationMethod(SingleLineTransformationMethod.getInstance());
        }
    } else {
        if (changeMaxLines) {
            setMaxLines(Integer.MAX_VALUE);
        }
        setHorizontallyScrolling(false);
        if (applyTransformation) {
            setTransformationMethod(null);
        }
    }
    

    }