web-dev-qa-db-fra.com

Police de l'indice de mot de passe dans Android

Lorsqu'un EditText est en mode mot de passe, il semble que l'indicateur est affiché dans une police différente (courrier?). Comment puis-je éviter ça? Je voudrais que l'indice apparaisse dans la même police que lorsque EditText n'est pas en mode mot de passe.

Mon xml actuel:

<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

Changer la police de caractère au format XML ne fonctionnait pas non plus pour le texte de conseil. J'ai trouvé deux solutions différentes, la seconde a un meilleur comportement pour moi:

1) Supprimer Android:inputType="textPassword" à partir de votre fichier xml et à la place, définissez-le en Java:

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

Avec cette approche, la police d’affichage a l’air bien, mais lorsque vous tapez dans ce champ de saisie, vous ne voyez pas chaque caractère en texte brut avant qu’il ne se transforme en point de mot de passe. De plus, lors de la saisie en plein écran, les points n'apparaîtront pas, mais le mot de passe en texte clair.

2) Quitter Android:inputType="textPassword" dans votre XML. En Java, définissez également la police de caractères et le mot de passe passwordMethod:

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

Cette approche m'a donné la police de caractère que je voulais ET m'a donné le comportement que je veux avec les points de mot de passe.

J'espère que ça t'as aidé!

383
manisha

J'ai trouvé cette astuce utile de Dialogs Guide

Conseil: Par défaut, lorsque vous définissez un élément EditText pour utiliser le type d'entrée "textPassword", la famille de polices est définie sur monospace. Vous devez donc modifier sa famille de polices en "sans-serif" afin que les deux champs de texte utilisent une police correspondante. style.


Par exemple

Android:fontFamily="sans-serif"
188
aysonje

C'est ce que j'ai fait pour résoudre ce problème. Pour une raison quelconque, je n'avais pas à définir la méthode de transformation, ce qui pourrait être une meilleure solution:

Dans mon xml:

<EditText
    Android:id="@+id/password_edit_field"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:hint="Password"
    Android:inputType="textPassword" />

Dans mon Activity:

EditText password = (EditText) findViewById( R.id.password_edit_field );
password.setTypeface( Typeface.DEFAULT );
32
James McCracken

L'approche setTransformationMethod rompt Android: imeOption pour moi et permet de saisir les retours chariot dans le champ du mot de passe. Au lieu de cela, je fais ceci:

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

Et je ne mets pas Android: password = "true" en XML.

21
rjrjr

La réponse fournie par manisha fonctionne, mais le champ de mot de passe reste dans un état non standard par rapport à celui par défaut. C'est-à-dire que la fontface par défaut s'applique également au champ de mot de passe, y compris les remplacements de points et les caractères de prévisualisation qui apparaissent avant d'être remplacés par les points (ainsi que lorsqu'il s'agit d'un champ "mot de passe visible").

Pour résoudre ce problème et lui donner 1) son apparence et agir exactement comme le type d'entrée par défaut textPassword, mais aussi 2) pour que le texte d'indication apparaisse dans une police par défaut (non monospace), vous devez disposer d'un TextWatcher sur le champ permettant de basculer correctement la fontface entre Typeface.DEFAULT et Typeface.MONOSPACE, qu'elle soit vide ou non. J'ai créé une classe d'assistance qui peut être utilisée pour accomplir cela:

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

Ensuite, pour l'utiliser, il suffit d'appeler la méthode register(View) static. Tout le reste est automatique (y compris le contournement de la solution de contournement si la vue ne l'exige pas!):

    final EditText txtPassword = (EditText) view.findViewById(R.id.txt_password);
    PasswordFontfaceWatcher.register(txtPassword);
5
Joe

Il existe de nombreuses façons de résoudre ce problème, mais chaque solution présente des avantages et des inconvénients. Voici mes tests

Je ne fais que faire face à ce problème de police dans un périphérique (liste à la fin de ma réponse) lors de l'activation du mot de passe

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

Si j'utilise Android:inputType="textPassword", Ce problème n'est pas arrivé

Quelque chose que j'ai essayé

1) Utilisez setTransformationMethod à la place inputType

edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
  • La police fonctionnera bien
  • Affichage du clavier pas très bien (il n’affiche que du texte, n’affiche pas de numéro en haut du texte)

2) Utilisez Typeface.DEFAULT

setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);
  • Le clavier affiche bien ,
  • La police peut ne pas fonctionner correctement . L'exemple sans-serif-light Est une police par défaut pour tous les View de mon application => après setTypeface(Typeface.DEFAULT), la police EditText a toujours l'aspect différent dans un périphérique

3) Utilisez Android:fontFamily="sans-serif"

Ma solution

cache le caractère avant setInputType puis le réutilise

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

Test
Problème de police lié à certains périphériques

  • Xiaomi A2 (8.0.1)
  • Pixel XL (8.1.0)
  • Sony Xperia Z5 Au (SOV32) (6.0)
  • Flèche NX (F-04G) (6.0.1)
  • Kyocera (S2) (7.0)

Certains appareils ne font pas face à un problème de police

  • Samsung S4 (SC-04E) (5.0.1)
  • Samsung Galaxy Node 5 (5.1.1)
  • Samsung S7 Edge (SM-G935F) (7.0)
5
Phan Van Linh

Les autres réponses sont la bonne solution pour la plupart des cas.

Toutefois, si vous utilisez une sous-classe EditText personnalisée pour, par exemple, appliquer une police personnalisée par défaut, il existe un problème subtil. Si vous définissez la police personnalisée dans le constructeur de votre sous-classe, elle sera toujours remplacée par le système si vous définissez inputType="textPassword".

Dans ce cas, déplacez votre style sur onAttachedToWindow après votre super.onAttachedToWindow appel.

Exemple d'implémentation:

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

Vous pouvez également utiliser un widget personnalisé. C'est très simple et cela n'encombre pas votre code d'activité/fragment.

Voici le code:

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

Et votre XML ressemblera à ceci:

<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

Je sais que c’est peut-être l’ancien, mais j’ai eu un problème avec ce problème lorsque j’utilisais InputTypeet app:passwordToggleEnabled="true" Ensemble.

Alors, écrivez ceci, car cela peut aider quelqu'un d’ici.

Je souhaite utiliser un champ de police personnalisé avec mot de passe avec l'option app:passwordToggleEnabled Pour mon champ de saisie de mot de passe. Mais dans 27.1.1 (en écrivant cela), la bibliothèque de support s’effondrait.

Donc, le code était comme ci-dessous,

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

Le code ci-dessus n'a pas inputType défini en XML

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

Et en Java, setTransformationMethod m'aidera à acquérir les propriétés du type d'entrée textPassword et je suis également heureux de mon style de police personnalisé.

Mais le crash mentionné ci-dessous s'est produit dans tous les niveaux d'API avec la bibliothèque de support 27.1.1.

Java.lang.NullPointerException: tentative d'appel de la méthode virtuelle 'void Android.support.design.widget.CheckableImageButton.setChecked (boolean)' sur une référence d'objet null

Cela plantait à cause de la classe onRestoreInstanceState à l'intérieur de la classe TextInputLayout.

Étapes de la reproduction: Basculez la visibilité du mot de passe, réduisez l'application et ouvrez-la à partir des applications récentes. Euh, ho s'est écrasé!

Tout ce dont j'avais besoin, c’était l’option de basculement du mot de passe par défaut (à l’aide de la bibliothèque de support technique) et d’une police personnalisée dans le champ de saisie du mot de passe.

Après un certain temps, compris comme ci-dessous,

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

En XML, ajouté 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

Dans ci-dessus Java code,

J'ai acquis le caractère personnalisé à partir du nom d'utilisateur EditText et je l'ai appliqué à TextInputLayout du champ mot de passe. Maintenant, vous n'avez pas besoin de définir explicitement le type de caractère avec le mot de passe EditText car il acquerra la propriété TextInputLayout.

J'ai aussi enlevé password.setTransformationMethod(new PasswordTransformationMethod());

De cette façon, passwordToggleEnabled fonctionne, la police personnalisée est également appliquée et adieu à l’incident. J'espère que ce problème sera résolu dans les prochaines versions de support.

2
Kavin Prabhu

utilisez le bibliothèque de calligraphie .

alors il ne sera toujours pas mettre à jour les champs de mot de passe avec la bonne police. alors faites ceci en code pas en 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

J'utilise cette solution pour basculer la police de caractères en fonction de la visibilité des indices. C'est similaire à la réponse de Joe, mais l'extension EditText à la place:

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

Un cas étrange peut-être, mais j'ai expérimenté cela et découvert que:

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

a changé le taille de la police de l'indice au lieu de la police elle-même! C'est toujours un effet indésirable. Curieusement, l'opération inverse:

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

Conserve la même taille de police.

0
MPelletier

Si vous utilisez le bibliothèque de calligraphie avec un TextInputLayout et un EditText, le code suivant fonctionne bien.

    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
Philipp Hellmayr

J'ai trouvé une solution sûre à ce problème

Meilleur moyen de Bonjour, j'ai trouvé une solution sûre à ce problème

La meilleure méthode consiste à créer un editText personnalisé et à enregistrer la valeur de la police typographique en tant que temp, puis à appliquer la méthode aux modifications apportées à InputType. Enfin, nous réinitialisons la valeur du type temp sur face à editText. ainsi :

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

Vous pouvez également utiliser le

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

ensemble avec

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

J'ai récemment ajouté la possibilité d'activer/désactiver l’activation/désactivation de Monospace en un extension de EditText spécifiquement pour les mots de passe, cela peut aider certaines personnes. Il n'utilise pas Android:fontFamily donc est compatible <16.

0
scottyab