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)看起来和行动完全一样的默认textPassword
inputtypes,但也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中没有大胆的风格,因为即使使用上面的修复,它们也不会看起来一样!