web-dev-qa-db-ja.com

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

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

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

1)xmlファイルからAndroid:inputType="textPassword"を削除し、代わりにJavaで設定します:

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

このアプローチでは、ヒントフォントは見栄えがよくなりますが、その編集フィールドに入力しているときに、パスワードドットになる前にプレーンテキストの各文字が表示されません。また、フルスクリーンで入力する場合、ドットは表示されませんが、パスワードはクリアテキストで表示されます。

2)xmlにAndroid:inputType="textPassword"を残します。 Javaでは、書体とpasswordMethodも設定します。

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

このアプローチは、私が欲しかったヒントフォントを与え、パスワードドットで私が望む振る舞いを与えました。

お役に立てば幸いです!

383
manisha

Dialogs Guide からこの便利なヒントを見つけました

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


例えば

Android:fontFamily="sans-serif"
188
aysonje

これは私がこの問題を解決するためにしたことです。何らかの理由で変換方法を設定する必要がなかったので、これがより良い解決策になるかもしれません。

私の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 );
32
James McCracken

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

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

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

21
rjrjr

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

これを修正して、1)デフォルトのtextPassword入力タイプとまったく同じように表示および動作するが、2)ヒントテキストをデフォルト(非等幅)フォントで表示できるようにするには、TextWatcherフィールドが空であるかどうかに基づいて、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);
5
Joe

この問題を解決する方法はたくさんありますが、それぞれの方法には長所と短所があります。これが私のテストです

私はface一部のデバイス(回答の最後にリスト)でこのフォントの問題を入力パスワードを有効にするときにのみ

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フォントはdifferent一部のデバイス

3)Android:fontFamily="sans-serif"を使用します

私のソリューション

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)
  • サムスンS7エッジ(SM-G935F)(7.0)
5
Phan Van Linh

他の答えは、ほとんどの場合に適切なソリューションです。

ただし、カスタム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 [email protected]
 */
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()));
        }
    }
}
4
Cory Petosky

カスタムウィジェットを使用することもできます。これは非常にシンプルで、アクティビティ/フラグメントのコードが乱雑になりません。

コードは次のとおりです。

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" />
2
Aldo Borrero

これは古いものかもしれませんが、InputTypeapp: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>

上記のコードにはinputTypeがXMLで定義されていません

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

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

しかし、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
Kavin Prabhu

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

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

このソリューションを使用して、ヒントの可視性に応じて書体を切り替えます。 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
KTCO

おそらく奇妙なケースですが、私はこれを実験して、次のことを発見しました:

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

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

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

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

0
MPelletier

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

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

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

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

}
0
Mr.Hosseini

を使用することもできます

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

一緒に

<Android.support.v7.widget.AppCompatEditText/>
0
DoruChidean

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

0
scottyab