260

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

18 に答える 18

400

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

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

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

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

android:inputType="textPassword"2) xml に残します。Java では、typeface と passwordMethod も設定します。

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

このアプローチにより、必要なヒントフォントが得られ、パスワードドットで必要な動作が得られました。

それが役立つことを願っています!

于 2010-08-09T23:13:46.067 に答える
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 );
于 2012-09-17T16:39:53.940 に答える
22

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

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

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

于 2012-01-03T19:38:51.327 に答える
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);
于 2013-07-10T22:32:46.240 に答える
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()));
        }
    }
}
于 2015-02-26T20:05:27.727 に答える
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>

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

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、書体を明示的にパスワードに設定する必要はありません。EditTextTextInputLayout

また、取り外しましたpassword.setTransformationMethod(new PasswordTransformationMethod());

こうすることで、passwordToggleEnabled動作し、カスタムフォントも適用され、クラッシュとはさようなら。この問題は、今後のサポート リリースで修正されることを願っています。

于 2018-07-06T07:48:37.127 に答える
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" />
于 2013-06-04T19:35:13.817 に答える
0

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

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

最善の方法は、カスタム 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);
        }
    }

}
于 2019-05-01T17:50:26.097 に答える
0

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

于 2016-01-06T09:42:49.087 に答える
-2

上記と同様ですが、上記の修正を行ってもフィールドが同じように表示されないため、xml でフィールドが太字スタイルにならないようにしてください。

于 2010-10-29T11:28:45.483 に答える