当EditText处于密码模式时,提示似乎以不同的字体显示(courier ?)我该如何避免这种情况?我想提示出现在相同的字体,当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" />

当前回答

解决这个问题有很多方法,但每种方法都有优缺点。下面是我的测试

我只面对这个字体问题在某些设备(列表在我的答案)时启用输入密码由

edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);

如果我使用android:inputType="textPassword",这个问题不会发生

我曾经尝试过

1)使用setTransformationMethod代替inputType

edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());

字体效果会很好 键盘显示不太好(只能显示文本,不能在文本上方显示数字)

2)使用字体。默认的

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

键盘显示良好, 字体可能工作不太好。示例sans-serif-light是我的应用程序中所有视图的默认字体= setTypeface(Typeface.DEFAULT)后面的>,EditText字体在某些设备中仍然看起来不同

3)使用android:fontFamily="sans-serif"

对于一些设备,它会崩溃,检查我的答案在这里https://stackoverflow.com/a/52421199/5381331。字体看起来也不一样

我的解决方案

在setInputType之前缓存字体,然后重用它

Typeface cache = edtPassword.getTypeface();
edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
edtPassword.setTypeface(cache);

测试 一些设备面临字体问题

小米A2 (8.0.1) Pixel XL (8.1.0) Sony Xperia Z5 Au (SOV32) (6.0) 箭NX (F-04G) (6.0.1) 京瓷(S2) (7.0)

一些设备不面临字体问题

三星S4 (SC-04E) (5.0.1) 三星Galaxy Node 5 (5.1.1) 三星S7 Edge (SM-G935F) (7.0)

其他回答

解决这个问题有很多方法,但每种方法都有优缺点。下面是我的测试

我只面对这个字体问题在某些设备(列表在我的答案)时启用输入密码由

edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);

如果我使用android:inputType="textPassword",这个问题不会发生

我曾经尝试过

1)使用setTransformationMethod代替inputType

edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());

字体效果会很好 键盘显示不太好(只能显示文本,不能在文本上方显示数字)

2)使用字体。默认的

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

键盘显示良好, 字体可能工作不太好。示例sans-serif-light是我的应用程序中所有视图的默认字体= setTypeface(Typeface.DEFAULT)后面的>,EditText字体在某些设备中仍然看起来不同

3)使用android:fontFamily="sans-serif"

对于一些设备,它会崩溃,检查我的答案在这里https://stackoverflow.com/a/52421199/5381331。字体看起来也不一样

我的解决方案

在setInputType之前缓存字体,然后重用它

Typeface cache = edtPassword.getTypeface();
edtPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
edtPassword.setTypeface(cache);

测试 一些设备面临字体问题

小米A2 (8.0.1) Pixel XL (8.1.0) Sony Xperia Z5 Au (SOV32) (6.0) 箭NX (F-04G) (6.0.1) 京瓷(S2) (7.0)

一些设备不面临字体问题

三星S4 (SC-04E) (5.0.1) 三星Galaxy Node 5 (5.1.1) 三星S7 Edge (SM-G935F) (7.0)

使用书法图书馆。

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

manisha提供的答案是可以工作的,但是与默认值相比,它使密码字段处于非标准状态。也就是说,默认字体也应用于密码字段,包括圆点替换和在被圆点替换之前出现的预览字符(以及当它是“可见密码”字段时)。

为了解决这个问题,并使它1)看起来和行为完全像默认的textPassword输入类型,但也2)允许提示文本出现在默认(非monospace)字体,你需要在字段上有一个TextWatcher,可以在字体之间正确地切换字体。默认和字体。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);

您还可以使用自定义小部件。它非常简单,并且不会使你的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" />

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

关于XML:

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

活动介绍:

inputPassword.setTypeface(Typeface.DEFAULT);

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