Android中的密码提示字体

当EditText处于密码模式时,似乎提示以不同的字体显示(courrier?)。 我怎样才能避免这一点? 我希望提示出现在EditText不处于密码模式的字体中。

我当前的XML:

<EditText android:hint="@string/edt_password_hint" android:layout_width="fill_parent" android:layout_height="wrap_content" android:password="true" android:singleLine="true" /> 

改变xml中的字体也不适用于我的提示文本。 我发现了两个不同的解决scheme,其中第二个对我来说有更好的行为:

1)从你的xml文件中删除android:inputType="textPassword" ,而是在java:

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

使用这种方法,提示字体看起来不错,但是当您在该编辑字段中input内容时,在转换为密码点之前,不会以纯文本forms查看每个字符。 另外,在全屏input时,不会出现点,而是明文中的密码。

2)在你的xml中留下android:inputType="textPassword" 。 在Java中,还要设置字体和密码方法:

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

这种方法给了我想要的提示字体,并给了我想要的密码点的行为。

希望有所帮助!

我从“ 对话框指南”中find了这个有用的提示

提示:默认情况下,当您将EditText元素设置为使用“textPassword”inputtypes时,字体系列设置为等宽字体,因此应将其字体系列更改为“sans-serif”,以使两个文本字段使用匹配的字体样式。


例如

 android:fontFamily="sans-serif" 

这是我所做的解决这个问题。 出于某种原因,我不必设置转换方法,所以这可能是一个更好的解决scheme:

在我的xml中:

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

在我的Activity

 EditText password = (EditText) findViewById( R.id.password_edit_field ); password.setTypeface( Typeface.DEFAULT ); 

setTransformationMethod方法为我打破了android:imeOption,并允许回车键入到密码字段。 相反,我正在这样做:

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

而不是在XML中设置android:password =“true”。

manisha提供的答案确实有效,但是与默认相比,它将密码字段保留在非标准状态。 也就是说,默认字体也适用于密码字段,包括点replace和用点代替之前出现的预览字符(以及它是“可见密码”字段时)。

要解决这个问题,并使其1)看起来和行动完全一样的默认textPasswordinputtypes,但也2)允许提示文本出现在默认(非等宽字体)的字体,你需要有一个TextWatcher的字段,可以在Fontface.DEFAULT和Typeface.MONOSPACE之间来回切换Fontface是否为空。 我创build了一个可以用来完成的辅助类:

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

那么要利用它,你所要做的就是调用register(View)静态方法。 其他一切都是自动的(包括在视图不需要的情况下跳过解决方法!):

  final EditText txtPassword = (EditText) view.findViewById(R.id.txt_password); PasswordFontfaceWatcher.register(txtPassword); 

您也可以使用自定义的Widget。 这是非常简单的,它不会凌乱你的活动/片段代码。

代码如下:

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

而你的XML将如下所示:

 <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" /> 

其他答案是大多数情况下的正确解决scheme。

但是,如果您使用自定义的EditText子类来默认应用自定义字体,则存在一个细微的问题。 如果您在子类的构造函数中设置了自定义字体,那么如果您设置了inputType="textPassword" ,它仍然会被系统覆盖。

在这种情况下,在super.onAttachedToWindow调用之后将样式移动到onAttachedToWindow

示例实现:

 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 cory@petosky.net */ 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())); } } } 

使用书法库 。

那么它仍然不会用正确的字体更新密码字段。 所以在代码中不要使用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); 

我最近添加了将切换等宽开关切换为EditText的扩展function,专门用于密码,可以帮助一些人。 它不使用android:fontFamily因此兼容<16。

你也可以使用

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

和…一起

 <android.support.v7.widget.AppCompatEditText/> 

我使用此解决scheme根据提示可见性切换字体。 这与Joe的回答类似,但是扩展了EditText:

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

如果您将书法库与TextInputLayout和EditText结合使用,则以下代码运行良好。

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

也许是一个奇怪的情况,但我已经尝试了这一点,发现:

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

改变了提示字体大小,而不是字体本身! 这仍然是一个不希望的结果。 奇怪的是,相反的操作:

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

保持相同的字体大小。

这如何使input密码有提示,而不是转换为*和默认字体!!

在XML上:

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

活动时间:

 inputPassword.setTypeface(Typeface.DEFAULT); 

感谢:芒果和rjrjr的洞察力:D。

像上面那样,但要确保这些字段在xml中没有大胆的风格,因为即使使用上面的修复,它们也不会看起来一样!