fonts - Fuente de sugerencia de contraseña en Android




passwords android-edittext (15)

Cuando un texto de edición está en modo de contraseña, parece que la sugerencia se muestra en una fuente diferente (¿mensajero?). ¿Cómo puedo evitar esto? Me gustaría que la sugerencia aparezca en la misma fuente que cuando EditText no está en modo de contraseña.

Mi xml actual:

<EditText 
android:hint="@string/edt_password_hint"
android:layout_width="fill_parent"
android:layout_height="wrap_content" 
android:password="true"
android:singleLine="true" />

Answers

El enfoque setTransformationMethod rompe android: imeOption para mí y permite que los retornos de carro se ingresen en el campo de contraseña. En cambio estoy haciendo esto:

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

Y no estoy configurando android: password = "true" en XML.


También puede utilizar un widget personalizado. Es muy simple y no desordena su código de Actividad / Fragmento.

Aquí está el código:

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

Y tu XML se verá así:

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

Cambiar el tipo de letra en xml tampoco funcionó en el texto de la pista. Encontré dos soluciones diferentes, la segunda de las cuales tiene mejor comportamiento para mí:

1) Elimine android:inputType="textPassword" de su archivo xml y en su lugar, android:inputType="textPassword" en java:

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

Con este enfoque, la fuente de la sugerencia se ve bien, pero mientras escribe en ese campo de edición, no verá cada carácter en texto sin formato antes de que se convierta en un punto de contraseña. También cuando se hace una entrada en pantalla completa, los puntos no aparecerán, pero la contraseña en texto claro.

2) Deja android:inputType="textPassword" en tu xml. En Java, TAMBIÉN establece el tipo de letra y el Método de contraseña:

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

Este enfoque me dio la fuente de pistas que quería y el comportamiento que quiero con los puntos de contraseña.

¡Espero que ayude!


Las otras respuestas son la solución correcta para la mayoría de los casos.

Sin embargo, si está utilizando una subclase de EditText personalizada para, digamos, aplicar una fuente personalizada de forma predeterminada, existe un problema sutil. Si configura la fuente personalizada en el constructor de su subclase, el sistema aún la sobrescribirá si establece inputType="textPassword" .

En este caso, mueva su estilo a onAttachedToWindow después de su llamada super.onAttachedToWindow .

Ejemplo de implementación:

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

Esta forma de crear una contraseña de entrada tiene una pista que no se convierte a * y el tipo de letra predeterminado.

En XML:

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

En Actividad:

inputPassword.setTypeface(Typeface.DEFAULT);

gracias a: mango y rjrjr por la idea: D.


La respuesta que proporcionó manisha funciona, pero deja el campo de contraseña en un estado no estándar en comparación con el valor predeterminado. Es decir, la fuente tipográfica predeterminada también se aplica al campo de la contraseña, incluidos los reemplazos de puntos y los caracteres de vista previa que aparecen antes de ser reemplazados por los puntos (así como cuando es un campo de "contraseña visible").

Para solucionar esto y hacer que 1) se vea y actúe exactamente como el tipo de entrada de textPassword del texto predeterminado, pero también 2) permita que el texto de la sugerencia aparezca en una fuente predeterminada (no monoespaciada), debe tener un TextWatcher en el campo que pueda alternar la fuente correctamente entre Typeface.DEFAULT y Typeface.MONOSPACE función de si está vacío o no. Creé una clase de ayuda que se puede usar para lograr eso:

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://.com/questions/3406534/password-hint-font-in-android">http://.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);
    }
}

Luego, para utilizarlo, todo lo que necesita hacer es llamar al método estático de register(View) . Todo lo demás es automático (incluido omitir la solución alternativa si la vista no lo requiere):

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

Recientemente, agregué la capacidad de cambiar la activación / desactivación de monospace a una extensión de EditText específicamente para contraseñas que puede ayudar a algunas personas. No usa android:fontFamily por lo que es compatible <16.


Utilizo esta solución para cambiar el tipo de letra según la visibilidad de la pista. Es similar a la respuesta de Joe, pero extendiendo EditText en su lugar:

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

}

como el anterior, pero asegúrese de que los campos no tengan el estilo en negrita en xml, ya que nunca se verán igual, incluso con la solución anterior.


Hay muchas maneras de resolver este problema, pero cada forma tiene sus pros y sus contras. Aquí está mi prueba

Solo enfrento este problema de fuente en algún dispositivo (lista al final de mi respuesta) cuando habilito la contraseña de entrada

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

Si uso android:inputType="textPassword" , este problema no ocurrió

Algo que he intentado

1) Utilice setTransformationMethod lugar de inputType

edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
  • La fuente funcionará bien
  • La pantalla del teclado no está muy bien (solo muestra el texto, no muestra el número encima del texto)

2) Utilice Typeface.DEFAULT

setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);
  • Teclado con pantalla bien ,
  • La fuente puede no funcionar bien . Ejemplo sans-serif-light es una fuente predeterminada para todos View en mi aplicación => después de setTypeface(Typeface.DEFAULT) , la fuente EditText aún se ve diferente en algún dispositivo

3) Usa android:fontFamily="sans-serif"

  • Para algunos dispositivos, CRASH , verifique mi respuesta aquí https://.com/a/52421199/5381331 . Y también la fuente todavía se ve diferente

MI SOLUCIÓN

caché el tipo de letra antes de setInputType luego reutilizarlo

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

Pruebas
Algunos problemas con la fuente del dispositivo

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

Algunos dispositivos no tienen problemas con la fuente

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

Esto es lo que hice para solucionar este problema. Por alguna razón, no tuve que configurar el método de transformación para que esta sea una mejor solución:

En mi xml:

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

En mi Activity :

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

Sé que este puede ser el más antiguo, pero me he metido en algo relacionado con este problema cuando usé InputType y app:passwordToggleEnabled="true" juntos.

Entonces, escribiendo esto, ya que puede ayudar a alguien aquí.

Quiero usar una fuente personalizada para el campo de contraseña junto con la opción app:passwordToggleEnabled para el campo de entrada de mi contraseña. Pero en 27.1.1 (mientras escribía esto) la biblioteca de soporte, estaba fallando.

Así que el código era como abajo,

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

El código anterior no tiene inputType definido en XML

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

Y en Java, setTransformationMethod me ayudará a adquirir las propiedades del tipo de entrada textPassword y también estoy contento con mi estilo de fuente personalizado.

Pero la falla mencionada a continuación ocurrió en todos los niveles de API con la biblioteca de soporte 27.1.1.

java.lang.NullPointerException: intento invocar el método virtual 'void android.support.design.widget.CheckableImageButton.setChecked (boolean) en una referencia de objeto nula

Esto se onRestoreInstanceState debido a onRestoreInstanceState dentro de la clase TextInputLayout .

Reproducir pasos: Alterne la visibilidad de la contraseña, minimice la aplicación y abra desde las aplicaciones recientes. Uh, Ho se estrelló!

Todo lo que necesito es la opción de cambio de contraseña predeterminada (usando la biblioteca de soporte) y la fuente personalizada en el campo de entrada de contraseña.

Después de un tiempo, lo descubrí haciendo lo siguiente:

<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, se agregó 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

En el código java anterior,

EditText tipo de letra personalizado del nombre de usuario EditText y lo apliqué a TextInputLayout del campo de contraseña. Ahora no necesita establecer el tipo de letra explícitamente en la contraseña EditText ya que adquirirá la propiedad TextInputLayout .

Además, eliminé password.setTransformationMethod(new PasswordTransformationMethod());

De esta manera, passwordToggleEnabled está funcionando, la fuente personalizada también se aplica y adiós al fallo. Espero que este problema se solucione en los próximos lanzamientos de soporte.


En caso de que esté utilizando la biblioteca de caligrafía en combinación con un TextInputLayout y un EditText, el siguiente código funciona 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);

Usa la biblioteca de caligrafía .

entonces todavía no actualizará los campos de contraseña con la fuente correcta. así que haz esto en código no 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); 

Una alternativa es usar scrypt, específicamente diseñado para ser superior a bcrypt por Colin Percival en su artículo . Hay una extensión de PHP scrypt en PECL . Idealmente, este algoritmo se incluiría en PHP para que se pueda especificar para las funciones password_ * (idealmente como "PASSWORD_SCRYPT"), pero aún no está disponible.





android fonts passwords android-edittext