Password hint font in Android
Asked Answered
O

18

260

When an EditText is in password mode, it seems that the hint is shown in a different font (courrier?). How can I avoid this? I would like the hint to appear in the same font that when the EditText is not in password mode.

My current xml:

<EditText 
android:hint="@string/edt_password_hint"
android:layout_width="fill_parent"
android:layout_height="wrap_content" 
android:password="true"
android:singleLine="true" />
Oudh answered 4/8, 2010 at 14:30 Comment(4)
Note that not all device behave this way. The "HTC One X @ 4.1.1" does (monospace). The "Samsung GT-7510 @4.0.4" does not. (same font)Bellini
Same behavior on LeWa OS 4.2.2. Too inconsistently API..Available
still exists in the lollipop alsoSethsethi
you can check my answer here hope it works.Accelerometer
F
400

Changing the typeface in xml didn't work on the hint text for me either. I found two different solutions, the second of which has better behavior for me:

  1. Remove android:inputType="textPassword" from your xml file and instead, in set it in java:

    EditText password = (EditText) findViewById(R.id.password_text); password.setTransformationMethod(new PasswordTransformationMethod());

With this approach, the hint font looks good but as you're typing in that edit field, you don't see each character in plain text before it turns into a password dot. Also when making input in fullscreen, the dots will not appear, but the password in clear text.

  1. Leave android:inputType="textPassword" in your xml. In Java, ALSO set the typeface and passwordMethod:

    EditText password = (EditText) findViewById(R.id.register_password_text); password.setTypeface(Typeface.DEFAULT); password.setTransformationMethod(new PasswordTransformationMethod());

This approach gave me the hint font I wanted AND gives me the behavior I want with the password dots.

Farandole answered 9/8, 2010 at 23:13 Comment(14)
Great, this is some strange behavior, you would not expect from default!Nuthouse
I used the standard password field type in XML and set the typeface in code. Worked great. Super annoying that this is set this way and can't overridden in XML.Plasticizer
Is the password.setTransformationMethod(new PasswordTransformationMethod()); necessary? Seems to work fine for me without.Slipway
Yes worked for me too. Thanks. The setTransformationMethod() call is not really necessary if android:password="true" is defined in the xml file.Solana
I did not need to use the setTransformationMethod() either. However, there are some side-effects of this approach that make it undesirable because it results in a non-standard behavior compared to the default textPassword behavior. For a more complete solution, see the helper class at: https://mcmap.net/q/109178/-password-hint-font-in-androidSimulated
@Joe: are the side-effects when using setTransformationMethod() or without? If I don't use that method, I have the desired styling.Hyperplane
This answer as a whole results in undesired behavior (see the answer linked from my comment for more information). The problem is that setting the font family impacts both the hint and the password bullets. My answer linked above has a solution that will override the font family while it's empty (so the hint appears in the correct style), and set it back to the monospace font when it is not empty (so the bullets appear uniform).Simulated
Better yet, look at this great simple solution in an answer right on this page: stackoverflow.com/a/18073897Mastodon
Please be aware that using the first solution is a bad idea - users that have auto-suggest enabled will start seeing their password in other apps, suggested to them, because the EditText was not declared as inputType="textPassword"Convalesce
This doesn't work with AppCompat - android.support.v7.widget.AppCompatEditText :(Darcee
Both the option works but as contradictory to comment by @Slipway if I don't set PasswordTransformation then it renders default typeface. Now if I set the TransformationMethod then Editor IME actions don't work.:(Shirty
Setting inputType=textPassword seems to have a side effect: The keyboard offers an uppercase for the first letter, textPassword being shorthand for TYPE_TEXT_VARIATION_PASSWORD | TYPE_CLASS_TEXT (128 + 1). Setting it to TYPE_TEXT_VARIATION_PASSWORD only prevents that.Julietajulietta
With these settings, I can see the password text on top of the keyboard.Mauromaurois
Don't remove android:inputType="textPassword" in first solution, use android:inputType="textVisiblePassword" instead, it will fix issues with non-default behavior and will disable text suggestionsUrrutia
N
197

I found this useful tip from Dialogs Guide

Tip: By default, when you set an EditText element to use the "textPassword" input type, the font family is set to monospace, so you should change its font family to "sans-serif" so that both text fields use a matching font style.


For example

android:fontFamily="sans-serif"
Nett answered 6/8, 2013 at 7:15 Comment(4)
This should be the accepted answer. It's simpler and it's from the docs.Mastodon
It's good, except that it only works on API level 16 and aboveBracteate
Note that while it only works on API level 16 and above, xml attributes don't cause crashes on older devices, they are just ignored.Lopez
It will not work if you click show/hide password several timesPhantasy
A
32

This is what I did to fix this problem. For some reason I didn't have to set the transformation method so this may be a better solution:

In my xml:

<EditText
    android:id="@+id/password_edit_field"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Password"
    android:inputType="textPassword" />

In my Activity:

EditText password = (EditText) findViewById( R.id.password_edit_field );
password.setTypeface( Typeface.DEFAULT );
Alumina answered 17/9, 2012 at 16:39 Comment(2)
I just tried it with textPassword in XML and as you were doing in the .java file, and it worked just fine. For me, it didn't seem to need the transformationSuannesuarez
Reminder: Call setTypeface() AFTER you change the InputType by code. setTransformationMethod not needed if InputType include xx_VARIATION_PASSWORD;Bellini
N
22

The setTransformationMethod approach breaks android:imeOption for me, and allows carriage returns to be typed into the password field. Instead I'm doing this:

setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);

And am not setting android:password="true" in XML.

N answered 3/1, 2012 at 19:38 Comment(1)
yap, this worked for me in 6.0.1 as well, the chosen answer did notStagnant
S
5

The answer manisha provided does work, but it leaves the password field in a nonstandard state compared to the default. That is, the default fontface then applies also to the password field, including both the dot replacements and the preview characters that appears before being replaced with the dots (as well as when it is a "visible password" field).

To fix this and make it 1) look and act exactly like the default textPassword input type, but also 2) allow the hint text to appear in a default (non-monospace) font, you need to have a TextWatcher on the field that can toggle the fontface properly back and forth between Typeface.DEFAULT and Typeface.MONOSPACE based on whether it is empty or not. I created a helper class that can be used to accomplish that:

import android.graphics.Typeface;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;

/**
 * This class watches the text input in a password field in order to toggle the field's font so that the hint text
 * appears in a normal font and the password appears as monospace.
 *
 * <p />
 * Works around an issue with the Hint typeface.
 *
 * @author jhansche
 * @see <a
 * href="https://mcmap.net/q/109178/-password-hint-font-in-android">https://mcmap.net/q/109178/-password-hint-font-in-android</a>
 */
public class PasswordFontfaceWatcher implements TextWatcher {
    private static final int TEXT_VARIATION_PASSWORD =
            (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
    private TextView mView;

    /**
     * Register a new watcher for this {@code TextView} to alter the fontface based on the field's contents.
     *
     * <p />
     * This is only necessary for a textPassword field that has a non-empty hint text. A view not meeting these
     * conditions will incur no side effects.
     *
     * @param view
     */
    public static void register(TextView view) {
        final CharSequence hint = view.getHint();
        final int inputType = view.getInputType();
        final boolean isPassword = ((inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))
                == TEXT_VARIATION_PASSWORD);

        if (isPassword && hint != null && !"".equals(hint)) {
            PasswordFontfaceWatcher obj = new PasswordFontfaceWatcher(view);
            view.addTextChangedListener(obj);

            if (view.length() > 0) {
                obj.setMonospaceFont();
            } else {
                obj.setDefaultFont();
            }
        }
    }

    public PasswordFontfaceWatcher(TextView view) {
        mView = view;
    }

    public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
        // Not needed
    }

    public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
        if (s.length() == 0 && after > 0) {
            // Input field went from empty to non-empty
            setMonospaceFont();
        }
    }

    public void afterTextChanged(final Editable s) {
        if (s.length() == 0) {
            // Input field went from non-empty to empty
            setDefaultFont();
        }
    }

    public void setDefaultFont() {
        mView.setTypeface(Typeface.DEFAULT);
    }

    public void setMonospaceFont() {
        mView.setTypeface(Typeface.MONOSPACE);
    }
}

Then to make use of it, all you need to do is call the register(View) static method. Everything else is automatic (including skipping the workaround if the view does not require it!):

    final EditText txtPassword = (EditText) view.findViewById(R.id.txt_password);
    PasswordFontfaceWatcher.register(txtPassword);
Simulated answered 10/7, 2013 at 22:32 Comment(2)
Nice work. One small change: if you set a font on the EditText (e.g. making the hint text Roboto Light), then setting Typeface.DEFAULT later will override this. I call field.getTypeface() up front and use that typeface whenever I need to reset to the "default" font later.Concertgoer
Well, calling field.getTypeface() doesn't seem to be 100% reliable (as often you'll just get back the monospace font), but creating a Typeface via Typeface.create() and then setting that seems to work well.Concertgoer
N
5

There are many way for solving this problem but each way have pros and cons. Here is my testing

I only face this font problem in some device (list at the end of my answer) when enable input password by

edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);

If I use android:inputType="textPassword", this problem don't happened

Something I have tried

1) Use setTransformationMethod instead inputType

edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
  • Font will working well
  • Keyboard display not very well (it only display text, don't display number on top of text)

2) Use Typeface.DEFAULT

setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);
  • Keyboard display well,
  • Font may working not well. Example sans-serif-light is a default font for all View in my application => after setTypeface(Typeface.DEFAULT), the EditText font still look different in some device

3) Use android:fontFamily="sans-serif"

MY SOLUTION

cache the typeface before setInputType then reuse it

Typeface cache = edtPassword.getTypeface();
edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
edtPassword.setTypeface(cache);

Testing
Some device face font problem

  • Xiaomi A2 (8.0.1)
  • Pixel XL (8.1.0)
  • Sony Xperia Z5 Au (SOV32) (6.0)
  • Arrow NX (F-04G) (6.0.1)
  • Kyocera (S2) (7.0)

Some device not face font problem

  • Samsung S4 (SC-04E) (5.0.1)
  • Samsung Galaxy Node 5 (5.1.1)
  • Samsung S7 Edge (SM-G935F) (7.0)
Neuropath answered 5/9, 2018 at 2:43 Comment(4)
What is the device (name and OS)?Ineffective
@Ineffective thank you for your suggestion, I have update device face font problem and device not face font problem base on my current deviceNeuropath
Thank you for a large testing! I came her from https://mcmap.net/q/111150/-programmatically-change-input-type-of-the-edittext-from-password-to-normal-amp-vice-versa. On Samsung S4 I used setTransformationMethod method (where not faced a problem).Ineffective
As I mention in my answer, setTransformationMethod will working but keyboard will not display well. However, if you oke with it, it still oke because it just a small problemNeuropath
S
4

The other answers are the right solution for most cases.

However, if you're using a custom EditText subclass to, say, apply a custom font by default, there's a subtle issue. If you set the custom font in the constructor of your subclass, it will still be overwritten by the system if you set inputType="textPassword".

In this case, move your styling to onAttachedToWindow after your super.onAttachedToWindow call.

Example implementation:

package net.petosky.android.ui;

import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.EditText;

/**
 * An EditText that applies a custom font.
 *
 * @author [email protected]
 */
public class EditTextWithCustomFont extends EditText {

    private static Typeface customTypeface;

    public EditTextWithCustomFont(Context context) {
        super(context);
    }

    public EditTextWithCustomFont(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextWithCustomFont(
            Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * Load and store the custom typeface for this app.
     *
     * You should have a font file in: project-root/assets/fonts/
     */
    private static Typeface getTypeface(Context context) {
        if (customTypeface == null) {
            customTypeface = Typeface.createFromAsset(
                    context.getAssets(), "fonts/my_font.ttf");
        }
        return customTypeface;
    }

    /**
     * Set a custom font for our EditText.
     *
     * We do this in onAttachedToWindow instead of the constructor to support
     * password input types. Internally in TextView, setting the password
     * input type overwrites the specified typeface with the system default
     * monospace.
     */
    @Override protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        // Our fonts aren't present in developer tools, like live UI
        // preview in AndroidStudio.
        if (!isInEditMode()) {
            setTypeface(getTypeface(getContext()));
        }
    }
}
Scrutator answered 26/2, 2015 at 20:5 Comment(0)
A
3

I know this may be the older one but I have humped into something related to this issue when I used InputTypeand app:passwordToggleEnabled="true"together.

So, writing this, as it may help someone over here.

I want to use a custom font to password field along with app:passwordToggleEnabled option for my password input field. But in 27.1.1 (while writing this) support library, it was crashing.

So the code was like below,

<android.support.design.widget.TextInputLayout
        android:id="@+id/input_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/_10dp"
        android:layout_marginTop="@dimen/_32dp"
        android:hint="@string/current_password"
        android:textColorHint="@color/hint_text_color"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:passwordToggleEnabled="true"
        app:passwordToggleTint="@color/black">


        <EditText
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="start|left"
            android:maxLines="1"
            android:textAlignment="viewStart"
            android:textColor="@color/black"
            android:textColorHint="@color/camel"
            android:textSize="@dimen/txt_16sp"
            app:font_style="regular"
            app:drawableEnd="@drawable/ic_remove_eye" />

    </android.support.design.widget.TextInputLayout>

Above code do not have inputType defined in XML

EditText password = (EditText) findViewById(R.id.password);
password.setTransformationMethod(new PasswordTransformationMethod());

And in Java, setTransformationMethod will help me acquire the properties of textPassword input type and also I'm happy my custom font style.

But the below-mentioned crash happened in all API levels with 27.1.1 support library.

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.design.widget.CheckableImageButton.setChecked(boolean)' on a null object reference

This was crashing due to the onRestoreInstanceState inside TextInputLayout class.

Reproduce Steps: Toggle the password visibility and minimize the app and open from the recent apps. Uh,ho Crashed!

All I needed is default password toggle option (using support library) and custom font in the password input field.

After some time, figured out by doing as below,

<android.support.design.widget.TextInputLayout
        android:id="@+id/input_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/_10dp"
        android:layout_marginTop="@dimen/_32dp"
        android:hint="@string/current_password"
        android:textColorHint="@color/hint_text_color"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:passwordToggleEnabled="true"
        app:passwordToggleTint="@color/black">


        <EditText
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="start|left"
            android:maxLines="1"
            android:textAlignment="viewStart"
            android:textColor="@color/black"
            android:textColorHint="@color/camel"
            android:textSize="@dimen/txt_16sp"
            app:font_style="regular"
            app:drawableEnd="@drawable/ic_remove_eye"
            android:inputType="textPassword" />

    </android.support.design.widget.TextInputLayout>

In XML, added android:inputType="textPassword"

TextInputLayout inputPassword = findViewById(R.id.input_password);
EditText password = findViewById(R.id.password);
EditText userName = findViewById(R.id.user_name);
// Get the typeface of user name or other edit text
Typeface typeface = userName.getTypeface();
if (typeface != null)
   inputLayout.setTypeface(typeface); // set to password text input layout

In above java code,

I acquired the custom typeface from username EditText and applied it to TextInputLayout of the password field. Now you don't need to set the typeface explicitly to the password EditText as it will acquire the TextInputLayout property.

Also, I removed password.setTransformationMethod(new PasswordTransformationMethod());

By doing this way, passwordToggleEnabled is working, the custom font is also applied and bye-bye to the crash. Hope this issue will be fixed in upcoming support releases.

Almonte answered 6/7, 2018 at 7:48 Comment(0)
D
2

You can also use a custom Widget. It's very simple and it doesn't clutter your Activity/Fragment code.

Here's the code:

public class PasswordEditText extends EditText {

  public PasswordEditText(Context context) {
    super(context);
    init();
  }

  public PasswordEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();

  }

  public PasswordEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
  }

  private void init() {
    setTypeface(Typeface.DEFAULT);
  }
}

And your XML will look like this:

<com.sample.PasswordEditText
  android:id="@+id/password_edit_field"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:hint="Password"
  android:inputType="textPassword"
  android:password="true" />
Dated answered 4/6, 2013 at 19:35 Comment(1)
In my experience this doesn't work -- internally TextView seems to overwrite the custom typeface after the constructor call. Provided a workaround in another answer.Scrutator
R
2

use the calligraphy library.

then it still wont update the password fields with the right font. so do this in code not in xml:

Typeface typeface_temp = editText.getTypeface();
editText.setInputType(inputType); /*whatever inputType you want like "TYPE_TEXT_FLAG_NO_SUGGESTIONS"*/
//font is now messed up ..set it back with the below call
editText.setTypeface(typeface_temp); 
Rushing answered 27/2, 2017 at 23:46 Comment(0)
H
0

I recently added the ability to change toggle monospace on/off to a extension of EditText specifically for passwords it may help some people. It doesn't use android:fontFamily so is compatible <16.

House answered 6/1, 2016 at 9:42 Comment(0)
I
0

You can also use the

<android.support.design.widget.TextInputLayout/>

together with

<android.support.v7.widget.AppCompatEditText/>
Incredulous answered 22/2, 2017 at 14:31 Comment(0)
S
0

I use this solution to toggle the Typeface depending on hint visibility. It's similar to Joe's answer, but extending EditText instead:

public class PasswordEditText extends android.support.v7.widget.AppCompatEditText {

    public PasswordEditText(Context context) {
        super(context);
    }

    public PasswordEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PasswordEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        if (text.length() > 0) setTypeface(Typeface.MONOSPACE);
        else setTypeface(Typeface.DEFAULT);
    }

}
Surtax answered 25/3, 2017 at 14:18 Comment(0)
M
0

In case you are using the calligraphy library in combination with a TextInputLayout and an EditText, the following code works well.

    EditText password = (EditText) findViewById(R.id.password);
    TextInputLayout passwordLayout = (TextInputLayout) findViewById(R.id.passwordLayout);

    Typeface typeface_temp = password.getTypeface();
    password.setInputType(InputType.TYPE_CLASS_TEXT |
            InputType.TYPE_TEXT_VARIATION_PASSWORD); 

    password.setTypeface(typeface_temp);
    passwordLayout.setTypeface(typeface_temp);
Morass answered 24/5, 2017 at 20:2 Comment(1)
This didn't modify my hint typefaceWeslee
J
0

A weird case perhaps, but I have experimented with this and found out that:

password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
password.setTransformationMethod(new PasswordTransformationMethod());

changed the size of the font of the hint instead of the font itself! This is still an undesired effect. Strangely enough, the reverse operation:

password.setTransformationMethod(new PasswordTransformationMethod());
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);

Keeps the same font size.

Julietajulietta answered 1/9, 2017 at 3:45 Comment(0)
M
0

I found a sure solution to this problem

Best way to Hello ,I found a sure solution to this problem

The best way is to create a custom editText and save value of typeface as a temp and then apply the method to the InputType changes , Finally, we set back the value of temp type face to the editText. like so :

public class AppCompatPasswordEditText extends AppCompatEditText {


    public AppCompatPasswordEditText(Context context) {
        super(context);
    }

    public AppCompatPasswordEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AppCompatPasswordEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        // Our fonts aren't present in developer tools, like live UI
        // preview in AndroidStudio.
        Typeface cache = getTypeface();

        if (!isInEditMode() && cache != null) {
            setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
            setTypeface(cache);
        }
    }

}
Mouldon answered 1/5, 2019 at 17:50 Comment(0)
H
-1

This how to make input password that has hint which not converted to * and default typeface !!.

On XML :

android:inputType="textPassword"
android:gravity="center"
android:ellipsize="start"
android:hint="Input Password !."

On Activity :

inputPassword.setTypeface(Typeface.DEFAULT);

thanks to : mango and rjrjr for the insight :D.

Handed answered 11/10, 2013 at 6:13 Comment(0)
S
-2

like the above but make sure the fields do not have the bold style in xml as they will never look the same even with the above fix!

Stillwell answered 29/10, 2010 at 11:28 Comment(1)
Don't say "above"...things change over time :-)Earthbound

© 2022 - 2024 — McMap. All rights reserved.