当 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" />
有帮助吗?

解决方案

在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中,还设置了字体和passwordMethod:

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

此方法给我的提示字体,我想,给我我想要的行为与密码点。

希望帮助!

其他提示

我发现从对话框指南

此有用的技巧
  

提示:在默认情况下,当你设置使用“textPassword”输入型一个EditText元素,字体系列设置为等宽,所以你应该它的字体系列变更为“无衬线”,使这两个文本字段使用匹配的字体样式。


例如

android:fontFamily="sans-serif"

这是我做过什么来解决这个问题。出于某种原因,我没有设置变换方法所以这可能是更好的解决方案:

在我的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方法场所机器人:imeOption我,并允许回车被键入到密码字段。相反,我这样做:

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

,我不设置机器人:密码=在XML“真”。

提供的答案MANISHA的工作,但它比默认的叶子在一个非标准的状态密码字段。也就是说,则默认fontface也适用于密码字段,包括点替换和预览字符都与该点被替换之前出现(以及当它是“可见的密码”字段)。

要解决这个问题,使之1)的外观和行为完全一样的默认textPassword输入类型,而且2)允许提示文本出现在默认(非等宽)字体,你需要对一个TextWatcher字段可以切换fontface正确来回基于Typeface.DEFAULTTypeface.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);

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

我只是 当启用输入密码时,某些设备中存在此字体问题(在我的答案末尾列出)

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 字体看起来仍然 不同的 在某些设备中

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

我的解决方案

缓存之前的字体 setInputType 然后重复使用它

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

测试
部分设备面临字体问题

  • 小米A2 (8.0.1)
  • 像素XL (8.1.0)
  • 索尼 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)

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

不过,如果您使用的是自定义的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()));
        }
    }
}

您也可以使用自定义的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" />

我知道这可能是旧的一个,但我已隆起到与当我用InputTypeand app:passwordToggleEnabled="true"together这个问题的东西。

所以,写这个,因为它可能会帮助别人在这里。

我要使用自定义字体密码字段我的密码输入栏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:尝试调用虚拟方法的空隙   android.support.design.widget.CheckableImageButton.setChecked(布尔值)”   上的空对象引用

这是崩溃由于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工作时,自定义字体也施加和再见到崩溃。希望这个问题将在即将到来的支持版本。

使用书法库

然后它仍然不会更新与正确的字体的口令字段。所以这样做是不代码以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的延伸具体的口令它可以帮助一些人。它不使用android:fontFamily所以兼容<16。

您还可以使用

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

连同

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

我使用此解决方案来切换根据提示可视性的字体。它类似于乔的答案,而是延伸的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);

保持相同的字体大小。

我发现了一个肯定的解决这个问题

要喂最好的方式,我发现了一个肯定的解决这个问题。

,最好的方法是创建一个定制EDITTEXT和保存字体的值作为一个临时然后将该方法应用到所述的inputType变化,最后,我们设置背面临时型面至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);
        }
    }

}

此如何使具有暗示其中未转化为*和默认字体输入密码!!

在XML:

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

在活动:

inputPassword.setTypeface(Typeface.DEFAULT);

由于:芒果和rjrjr为洞察:d

就像上面,但要确保领域不具备XML大胆的风格,因为他们将永远看起来是一样的,甚至与上面的修复!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top