Password hint font in Android
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);
Related videos on Youtube
hpique
iOS, Android & Mac developer. Founder of Robot Media. @hpique
Updated on May 02, 2020Comments
-
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 about 11 yearsNote 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 almost 10 yearsSame behavior on LeWa OS 4.2.2. Too inconsistently API..
-
Mightian over 9 yearsstill exists in the lollipop also
-
Dmila Ram over 7 yearsyou can check my answer here hope it works.
-
-
Sander Versluys almost 13 yearsGreat, this is some strange behavior, you would not expect from default!
-
Joe Plante almost 12 yearsI 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 over 11 yearsI 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 over 11 yearsIs the
password.setTransformationMethod(new PasswordTransformationMethod());
necessary? Seems to work fine for me without. -
ZaBlanc over 11 yearsDon't say "above"...things change over time :-)
-
Sileria about 11 yearsYes worked for me too. Thanks. The
setTransformationMethod()
call is not really necessary ifandroid:password="true"
is defined in the xml file. -
Ahmed Jihad about 11 yearsReminder: Call setTypeface() AFTER you change the InputType by code. setTransformationMethod not needed if InputType include xx_VARIATION_PASSWORD;
-
Joe almost 11 yearsI 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 defaulttextPassword
behavior. For a more complete solution, see the helper class at: stackoverflow.com/a/17582092/231078 -
Christopher Orr over 10 yearsNice work. One small change: if you set a font on the
EditText
(e.g. making the hint text Roboto Light), then settingTypeface.DEFAULT
later will override this. I callfield.getTypeface()
up front and use that typeface whenever I need to reset to the "default" font later. -
Christopher Orr over 10 yearsWell, calling
field.getTypeface()
doesn't seem to be 100% reliable (as often you'll just get back the monospace font), but creating a Typeface viaTypeface.create()
and then setting that seems to work well. -
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 over 10 yearsThis 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 about 10 yearsThis should be the accepted answer. It's simpler and it's from the docs.
-
Marcin Koziński about 10 yearsBetter yet, look at this great simple solution in an answer right on this page: stackoverflow.com/a/18073897
-
Ben Clayton about 10 yearsIt's good, except that it only works on API level 16 and above
-
Elad Nava over 9 yearsPlease 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 over 9 yearsIn 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 over 8 yearsNote 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 over 8 yearsThis doesn't work with AppCompat - android.support.v7.widget.AppCompatEditText :(
-
Nactus almost 8 yearsyap, this worked for me in 6.0.1 as well, the chosen answer did not
-
VishalKale over 7 yearsBoth 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 almost 7 yearsSetting
inputType=textPassword
seems to have a side effect: The keyboard offers an uppercase for the first letter,textPassword
being shorthand forTYPE_TEXT_VARIATION_PASSWORD | TYPE_CLASS_TEXT
(128 + 1). Setting it toTYPE_TEXT_VARIATION_PASSWORD
only prevents that. -
us2956 over 6 yearsWith these settings, I can see the password text on top of the keyboard.
-
Rafael Ruiz Muñoz almost 6 yearsThis didn't modify my hint typeface
-
CoolMind almost 6 yearsWhat is the device (name and OS)?
-
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 almost 6 yearsThank 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 almost 6 yearsAs 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 over 5 yearsIt will not work if you click show/hide password several times
-
GrafOrlov over 5 yearsDon'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