Androidのパスワードヒントフォント


255

EditTextがパスワードモードの場合、ヒントは別のフォント(クーリエ?)で表示されているようです。どうすればこれを回避できますか?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" />

1
すべてのデバイスがこのように動作するわけではないことに注意してください。「HTC One X @ 4.1.1」は(等幅)です。「Samsung GT-7510 @ 4.0.4」にはありません。(同じフォント)
Loda

1
LeWa OS 4.2.2で同じ動作。あまりにも矛盾API ...
RUX

ロリポップにもまだ存在します
マイティアン2015年

ここで私の答えを確認できます。
Dmila Ram 2016

回答:


394

xmlの書体を変更しても、ヒントテキストは機能しませんでした。私は2つの異なる解決策を見つけました。2つ目の解決策は私にとってより良い動作をします。

1)android:inputType="textPassword"xmlファイルから削除し、代わりに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());

このアプローチにより、私が欲しかったヒントフォントが得られ、パスワードドットで私が望んだ動作が得られました。

お役に立てば幸いです。


3
これは奇妙な動作です。デフォルトからは期待できません。
Sander Versluys、2011

15
であるpassword.setTransformationMethod(new PasswordTransformationMethod());必要?なしで私のためにうまく機能するようです。
loeschg

1
setTransformationMethod()どちらも使う必要はありませんでした。ただし、このアプローチには、デフォルトのtextPassword動作と比較して非標準の動作になるため、望ましくない副作用がいくつかあります。より完全なソリューションについては、次のヘルパークラスを参照してください。stackoverflow.com
Joe

10
いっそのこと、右のこのページの答えで、この偉大な簡単な解決策を見て:stackoverflow.com/a/18073897
マルチンKoziński

16
最初の解決策を使用するのは悪い考えです。自動提案を有効にしているユーザーは、EditTextがinputType="textPassword"
Elad Nava

193

ダイアログガイドからこの便利なヒントを見つけました

ヒント:デフォルトでは、「textPassword」入力タイプを使用するようにEditText要素を設定すると、フォントファミリーはモノスペースに設定されるため、両方のテキストフィールドで一致するフォントが使用されるように、フォントファミリーを「sans-serif」に変更する必要があります。スタイル。


例えば

android:fontFamily="sans-serif"

21
これは受け入れられる答えになるはずです。それはより簡単で、ドキュメントからのものです。
MarcinKoziński、2014

29
APIレベル16以上でのみ機能することを除いて、それは良いことです
Ben Clayton

6
これはAPIレベル16以上でのみ機能しますが、xml属性は古いデバイスではクラッシュを引き起こさず、無視されることに注意してください。
Adam Johns

パスワードの表示/非表示を数回クリックしても機能しません
Ali Habbash

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

XMLでtextPasswordを使用して、.javaファイルで行ったように試してみたところ、問題なく動作しました。私にとって、それは変換を必要とするようには見えませんでした
Joe Plante '21

2
注意:コードでInputTypeを変更した後で、setTypeface()を呼び出します。InputTypeにxx_VARIATION_PASSWORDが含まれている場合、setTransformationMethodは不要です。
ロダ2013年

21

setTransformationMethodアプローチはandroid:imeOptionを無効にし、キャリッジリターンをパスワードフィールドに入力できるようにします。代わりに私はこれをやっています:

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

XMLでandroid:password = "true"を設定していません。


うん、これは6.0.1でも私にとってはうまくいきました、選ばれた答えはうまく
いき

5

manishaが提供する回答は機能しますが、デフォルトと比較してパスワードフィールドが非標準の状態のままになります。つまり、デフォルトのフォントフェイスがパスワードフィールドにも適用されます。これには、ドットの置換と、ドットに置き換えられる前に表示されるプレビュー文字(および「可視パスワード」フィールドの場合)の両方が含まれます。

これを修正し、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);

1
よくやった。1つの小さな変更:にフォントを設定した場合EditText(たとえば、ヒントテキストRoboto Lightを作成した場合)、Typeface.DEFAULT後で設定するとこれが上書きされます。私はfield.getTypeface()前に呼び出し、後で「デフォルト」フォントにリセットする必要があるときはいつでもその書体を使用します。
Christopher Orr 2013

まあ、呼び出しfield.getTypeface()は100%信頼できるようではありません(多くの場合、等幅フォントを取得するだけです)Typeface.create()
Christopher Orr 2013

5

この問題を解決するには多くの方法がありますが、どちらの方法にも長所と短所があります。これが私のテストです

次の方法で入力パスワードを有効にすると、一部のデバイス(私の回答の最後にリスト)でのみこのフォントの問題に直面します

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-lightView私のアプリケーションのすべてのデフォルトフォントです=>後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);


いくつかのデバイスフェイスフォントの問題をテストする

  • Xiaomi A2(8.0.1)
  • Pixel XL(8.1.0)
  • ソニーXperia Z5 Au(SOV32)(6.0)
  • Arrow NX(F-04G)(6.0.1)
  • 京セラ(S2)(7.0)

一部のデバイスでフォントの問題が発生しない

  • サムスンS4(SC-04E)(5.0.1)
  • Samsung Galaxy Node 5(5.1.1)
  • Samsung S7 Edge(SM-G935F)(7.0)

デバイスとは何ですか(名前とOS)?
CoolMind 2018

1
@CoolMind私はない私の現在のデバイス上でのフォント問題のベースに直面更新デバイス顔フォントの問題やデバイスを持って、ご提案をありがとう
ファンティエットヴァンたLiNH

大規模なテストをありがとう!私はstackoverflow.com/a/52178340/2914140から彼女に来ました。サムスンS4では、setTransformationMethod方法を使用しました(問題に直面していない場合)。
CoolMind 2018

私の答えで述べたように、setTransformationMethod動作しますが、キーボードがうまく表示されません。しかし、あなたはそれでおけあれば、それはまだおけば、それだけで小さな問題ので
ファンティエットヴァンたLiNH

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

3

私はこれが古いものかもしれないことを知っていますが、私が一緒に使用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>

上記のコードはinputTypeXMLで定義されていません

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

Javaでは、入力タイプsetTransformationMethodのプロパティを取得するのに役立ちますtextPassword。また、カスタムフォントスタイルに満足しています。

しかし、下記のクラッシュは、27.1.1サポートライブラリのすべてのAPIレベルで発生しました。

java.lang.NullPointerException:nullオブジェクト参照で仮想メソッド「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が機能し、カスタムフォントも適用され、クラッシュに別れを告げます。この問題が今後のサポートリリースで修正されることを願っています。


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

私の経験では、これは機能しません-内部的にTextViewは、コンストラクター呼び出しの後にカスタム書体を上書きするようです。別の回答で回避策を提供しました。
Cory Petosky、2015

2

書道ライブラリを使用します

その後も、正しいフォントでパスワードフィールドを更新しません。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); 

0

最近、モノスペースのオン/オフの切り替えをEditTextの拡張機能に変更する機能を追加しました。これは、一部の人に役立つ可能性のあるパスワード専用です。それは使用しないandroid:fontFamilyので互換性があります<16。


0

あなたも使うことができます

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

一緒に

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

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

}

0

書道ライブラリを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);

これは私のヒント書体を変更しませんでした
Rafael

0

奇妙なケースかもしれませんが、私はこれを実験して、それを発見しました:

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

フォント自体ではなく、ヒントのフォントサイズを変更しました!これはまだ望ましくない影響です。奇妙なことに、逆の操作:

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

同じフォントサイズを維持します。


0

この問題の確実な解決策を見つけました

こんにちは、私はこの問題の確実な解決策を見つけました

最良の方法は、カスタムのeditTextを作成し、書体の値をtempとして保存してから、メソッドをInputTypeの変更に適用することです。最後に、tempの書体の値を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);
        }
    }

}

-1

このヒントは、*に変換されないヒントとデフォルトのタイプフェイス!!を持つ入力パスワードを作成する方法です。

XMLについて:

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

活動中:

inputPassword.setTypeface(Typeface.DEFAULT);

:Dの洞察をありがとう:mangoとrjrjr


-2

上記と同じですが、フィールドがxmlで太字にならないようにしてください。上記の修正を行ってもフィールドが同じように表示されることはありません。


2
「上」とは言わないでください...時間とともに変化します:-)
ZaBlanc 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.