Password hint font in Android

69,721

Solution 1

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.

2) 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.

Hope that helps!

Solution 2

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"

Solution 3

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 );

Solution 4

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.

Solution 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="http://stackoverflow.com/questions/3406534/password-hint-font-in-android">http://stackoverflow.com/questions/3406534/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);
Share:
69,721

Related videos on Youtube

hpique
Author by

hpique

iOS, Android &amp; Mac developer. Founder of Robot Media. @hpique

Updated on May 02, 2020

Comments

  • hpique
    hpique about 4 years

    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" />
    
    • Ahmed Jihad
      Ahmed Jihad about 11 years
      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)
    • ruX
      ruX almost 10 years
      Same behavior on LeWa OS 4.2.2. Too inconsistently API..
    • Mightian
      Mightian over 9 years
      still exists in the lollipop also
    • Dmila Ram
      Dmila Ram over 7 years
      you can check my answer here hope it works.
  • Sander Versluys
    Sander Versluys almost 13 years
    Great, this is some strange behavior, you would not expect from default!
  • Joe Plante
    Joe Plante almost 12 years
    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 transformation
  • profexorgeek
    profexorgeek over 11 years
    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.
  • loeschg
    loeschg over 11 years
    Is the password.setTransformationMethod(new PasswordTransformationMethod()); necessary? Seems to work fine for me without.
  • ZaBlanc
    ZaBlanc over 11 years
    Don't say "above"...things change over time :-)
  • Sileria
    Sileria about 11 years
    Yes worked for me too. Thanks. The setTransformationMethod() call is not really necessary if android:password="true" is defined in the xml file.
  • Ahmed Jihad
    Ahmed Jihad about 11 years
    Reminder: Call setTypeface() AFTER you change the InputType by code. setTransformationMethod not needed if InputType include xx_VARIATION_PASSWORD;
  • Joe
    Joe almost 11 years
    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: stackoverflow.com/a/17582092/231078
  • Christopher Orr
    Christopher Orr over 10 years
    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.
  • Christopher Orr
    Christopher Orr over 10 years
    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.
  • bplayer
    bplayer over 10 years
    @Joe: are the side-effects when using setTransformationMethod() or without? If I don't use that method, I have the desired styling.
  • Joe
    Joe over 10 years
    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).
  • Marcin Koziński
    Marcin Koziński about 10 years
    This should be the accepted answer. It's simpler and it's from the docs.
  • Marcin Koziński
    Marcin Koziński about 10 years
    Better yet, look at this great simple solution in an answer right on this page: stackoverflow.com/a/18073897
  • Ben Clayton
    Ben Clayton about 10 years
    It's good, except that it only works on API level 16 and above
  • Elad Nava
    Elad Nava over 9 years
    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"
  • Cory Petosky
    Cory Petosky over 9 years
    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.
  • Adam Johns
    Adam Johns over 8 years
    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.
  • Bharathwaaj
    Bharathwaaj over 8 years
    This doesn't work with AppCompat - android.support.v7.widget.AppCompatEditText :(
  • Nactus
    Nactus almost 8 years
    yap, this worked for me in 6.0.1 as well, the chosen answer did not
  • VishalKale
    VishalKale over 7 years
    Both the option works but as contradictory to comment by @loeschg if I don't set PasswordTransformation then it renders default typeface. Now if I set the TransformationMethod then Editor IME actions don't work.:(
  • MPelletier
    MPelletier almost 7 years
    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.
  • us2956
    us2956 over 6 years
    With these settings, I can see the password text on top of the keyboard.
  • Rafael Ruiz Muñoz
    Rafael Ruiz Muñoz almost 6 years
    This didn't modify my hint typeface
  • CoolMind
    CoolMind almost 6 years
    What is the device (name and OS)?
  • Linh
    Linh almost 6 years
    @CoolMind thank you for your suggestion, I have update device face font problem and device not face font problem base on my current device
  • CoolMind
    CoolMind almost 6 years
    Thank you for a large testing! I came her from stackoverflow.com/a/52178340/2914140. On Samsung S4 I used setTransformationMethod method (where not faced a problem).
  • Linh
    Linh almost 6 years
    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 problem
  • Ali Habbash
    Ali Habbash over 5 years
    It will not work if you click show/hide password several times
  • GrafOrlov
    GrafOrlov over 5 years
    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 suggestions