当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" />
答案 0 :(得分:375)
更改xml中的字体对我来说也不适用于提示文本。我发现了两种不同的解决方案,其中第二种解决方案对我有更好的行为:
1)从xml文件中删除android:inputType="textPassword"
,而不是在java中设置它:
EditText password = (EditText) findViewById(R.id.password_text);
password.setTransformationMethod(new PasswordTransformationMethod());
使用这种方法,提示字体看起来不错,但是当您在该编辑字段中键入时,在转换为密码点之前,您不会看到纯文本中的每个字符。此外,在全屏输入时,不会出现点,但密码以明文形式显示。
2)将android:inputType="textPassword"
留在xml中。在Java中,ALSO设置了字体和密码方法:
EditText password = (EditText) findViewById(R.id.register_password_text);
password.setTypeface(Typeface.DEFAULT);
password.setTransformationMethod(new PasswordTransformationMethod());
这种方法给了我想要的提示字体,并通过密码点给我了我想要的行为。
希望有所帮助!
答案 1 :(得分:187)
提示:默认情况下,当您将EditText元素设置为使用“textPassword”输入类型时,字体系列将设置为等宽字体,因此您应将其字体系列更改为“sans-serif”,以便两个文本字段都使用匹配的字体样式。
例如
android:fontFamily="sans-serif"
答案 2 :(得分:32)
这就是我为解决这个问题所做的工作。出于某种原因,我没有必要设置转换方法,因此这可能是一个更好的解决方案:
在我的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 );
答案 3 :(得分:21)
setTransformationMethod方法为我打破了android:imeOption,并允许在密码字段中输入回车符。相反,我这样做:
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);
我没有在XML中设置android:password =“true”。
答案 4 :(得分:5)
提供的答案manisha确实有效,但与默认状态相比,它使密码字段处于非标准状态。也就是说,默认字体也适用于密码字段,包括点替换和在用点替换之前出现的预览字符(以及当它是“可见密码”字段时)。
要修复此问题并使其1)看起来和行为完全类似于默认的textPassword
输入类型,还要2)允许提示文本以默认(非等宽)字体显示,您需要字段上的TextWatcher
,可根据字段是否为空来在Typeface.DEFAULT
和Typeface.MONOSPACE
之间来回切换字体。我创建了一个可以用来完成它的帮助器类:
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);
答案 5 :(得分:4)
有很多方法可以解决此问题,但每种方法各有利弊。这是我的测试
当通过
启用输入密码时,我只能在某些设备(答案末尾列出)中面对这种字体问题。edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
如果我使用android:inputType="textPassword"
,则此问题不会发生
1)使用setTransformationMethod
代替inputType
edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
2)使用Typeface.DEFAULT
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);
sans-serif-light
是我的应用程序中所有View
的默认字体=>在setTypeface(Typeface.DEFAULT)
之后,EditText
字体在某些设备上看起来仍然不同 < / li>
3)使用android:fontFamily="sans-serif"
在
setInputType
之前缓存字体,然后重新使用
Typeface cache = edtPassword.getTypeface();
edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
edtPassword.setTypeface(cache);
测试
某些设备字体字体问题
某些设备没有字体问题
答案 6 :(得分:4)
对于大多数情况,其他答案是正确的解决方案。
但是,如果您使用自定义EditText
子类,比如默认应用自定义字体,那么这是一个微妙的问题。如果在子类的构造函数中设置自定义字体,如果设置inputType="textPassword"
,系统仍会覆盖它。
在这种情况下,请在onAttachedToWindow
来电后将样式移至super.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()));
}
}
}
答案 7 :(得分:2)
您还可以使用自定义窗口小部件。它非常简单,它不会使您的Activity / Fragment代码混乱。
以下是代码:
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" />
答案 8 :(得分:1)
我知道这可能是较老的版本,但是当我同时使用InputType
和app:passwordToggleEnabled="true"
时,我就陷入了与此问题相关的问题。
所以,写这个,因为它可能对这里的人有帮助。
我想在密码输入字段中使用自定义字体作为密码字段以及app:passwordToggleEnabled
选项。但是在27.1.1(在编写此代码时)支持库中,它崩溃了。
所以代码如下:
<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>
以上代码没有用XML定义的inputType
EditText password = (EditText) findViewById(R.id.password);
password.setTransformationMethod(new PasswordTransformationMethod());
在Java中,setTransformationMethod
将帮助我获得textPassword
输入类型的属性,同时,我也很高兴自定义字体样式。
但是下面提到的崩溃发生在具有27.1.1支持库的所有API级别中。
java.lang.NullPointerException:尝试调用虚拟方法'void android.support.design.widget.CheckableImageButton.setChecked(boolean)' 在空对象引用上
由于onRestoreInstanceState
类中的TextInputLayout
,导致崩溃。
重现步骤:切换密码可见性并最小化该应用程序,并从最近的应用程序中打开。呃,坠毁了!
我需要的是默认的密码切换选项(使用支持库)和密码输入字段中的自定义字体。
一段时间后,通过以下操作找出答案
<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>
在XML中,添加了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
在上述Java代码中,
我从用户名EditText
获取了自定义字体,并将其应用于密码字段的TextInputLayout
。现在,您无需将字体显式设置为密码EditText
,因为它将获得TextInputLayout
属性。
我还删除了password.setTransformationMethod(new PasswordTransformationMethod());
通过这种方式,passwordToggleEnabled
可以正常工作,自定义字体也将应用到崩溃中并再见。希望此问题将在即将发布的支持版本中得到解决。
答案 9 :(得分:1)
然后它仍然不会使用正确的字体更新密码字段。所以在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);
答案 10 :(得分:0)
我最近添加了将切换等宽开关更改为extension of EditText的功能,专门用于可能对某些人有用的密码。它没有使用android:fontFamily
因此兼容&lt; 16。
答案 11 :(得分:0)
我找到了解决此问题的肯定方法
最好的方法,您好,我找到了解决此问题的可靠方法
最好的方法是创建一个自定义editText并将typeface的值另存为temp,然后将该方法应用于InputType更改,最后,将temp type face的值重新设置为editText。像这样:
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);
}
}
}
答案 12 :(得分:0)
也许是一个奇怪的案例,但我已经对此进行了实验并发现了:
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
password.setTransformationMethod(new PasswordTransformationMethod());
更改了提示的字体大小而不是字体本身!这仍然是不希望的效果。奇怪的是,反向操作:
password.setTransformationMethod(new PasswordTransformationMethod());
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
保持相同的字体大小。
答案 13 :(得分:0)
如果您将calligraphy library与TextInputLayout和EditText结合使用,以下代码效果很好。
captcha.php
答案 14 :(得分:0)
我使用此解决方案根据提示可见性切换字体。它与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);
}
}
答案 15 :(得分:0)
您也可以使用
<android.support.design.widget.TextInputLayout/>
与
一起<android.support.v7.widget.AppCompatEditText/>
答案 16 :(得分:-1)
如何输入具有未转换为*和默认字体的提示的输入密码!!。
在XML上:
android:inputType="textPassword"
android:gravity="center"
android:ellipsize="start"
android:hint="Input Password !."
活动:
inputPassword.setTypeface(Typeface.DEFAULT);
感谢:芒果和rjrjr的见解:D。
答案 17 :(得分:-2)
如上所述,但要确保字段在xml中没有粗体样式,因为即使使用上述修复它们也看起来不一样!