Шрифт подсказки пароля в Android
Когда EditText находится в режиме пароля, кажется, что подсказка отображается другим шрифтом (courrier?). Как я могу избежать этого? Я хотел бы, чтобы подсказка отображалась в том же шрифте, что и при редактировании 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
Изменение шрифта в xml также не сработало для текста подсказки. Я нашел два разных решения, второе из которых имеет лучшее поведение для меня:
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());
Этот подход дал мне шрифт подсказки, который я хотел И дал мне поведение, которое я хочу с точками пароля.
Надеюсь, это поможет!
Ответ 2
Я нашел этот полезный совет из Диалоговое окно
Совет. По умолчанию, когда вы устанавливаете элемент EditText для использования типа ввода "textPassword", семейство шрифтов устанавливается в моноширинное, поэтому вы должны изменить его семейство шрифтов на "sans-serif", чтобы использовать оба текстовых поля соответствующий стиль шрифта.
Например
android:fontFamily="sans-serif"
Ответ 3
Вот что я сделал, чтобы исправить эту проблему. По какой-то причине мне не нужно было устанавливать метод преобразования, чтобы это могло быть лучшим решением:
В моем 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 );
Ответ 4
Метод setTransformationMethod разбивает android: imeOption для меня и позволяет вводить данные каретки в поле пароля. Вместо этого я делаю это:
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
setTypeface(Typeface.DEFAULT);
И не устанавливаю android: password = "true" в XML.
Ответ 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 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 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);
Ответ 6
Другие ответы - правильное решение для большинства случаев.
Однако, если вы используете собственный подкласс 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 [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()));
}
}
}
Ответ 7
Есть много способов решения этой проблемы, но у каждого есть свои плюсы и минусы. Вот мое тестирование
Я сталкиваюсь с этой проблемой шрифтов только на каком-то устройстве (список в конце моего ответа) при включении ввода пароля
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
прежнему выглядит по- другому на некоторых устройствах
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)
- Пиксель XL (8.1.0)
- Sony Xperia Z5 Au (SOV32) (6,0)
- Стрелка NX (F-04G) (6.0.1)
- Kyocera (S2) (7,0)
Некоторые устройства не сталкиваются с проблемой шрифтов
- Samsung S4 (SC-04E) (5.0.1)
- Samsung Galaxy Node 5 (5.1.1)
- Samsung S7 Edge (SM-G935F) (7,0)
Ответ 8
Вы также можете использовать собственный виджет. Это очень просто и не загромождает ваш код 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" />
Ответ 9
используйте библиотеку каллиграфии.
то он по-прежнему не будет обновлять поля пароля правильным шрифтом. поэтому сделайте это в коде не в 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);
Ответ 10
Я знаю, что это может быть старая InputType
но я столкнулся с чем-то связанным с этой проблемой, когда я использовал 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
а также я доволен своим собственным стилем шрифта.
Но нижеупомянутый сбой произошел на всех уровнях API с библиотекой поддержки 27.1.1.
java.lang.NullPointerException: попытка вызвать виртуальный метод '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
работает, пользовательский шрифт также применяется и до свидания до сбоя. Надеюсь, что эта проблема будет исправлена в следующих выпусках поддержки.
Ответ 11
Недавно я добавил возможность изменять/отключать моноширину в режиме расширение EditText специально для паролей, это может помочь некоторым людям. Он не использует android:fontFamily
, поэтому совместим < 16.
Ответ 12
Вы также можете использовать
<android.support.design.widget.TextInputLayout/>
вместе с
<android.support.v7.widget.AppCompatEditText/>
Ответ 13
Я использую это решение для переключения Typeface в зависимости от видимости подсказки. Он похож на ответ Джо, но вместо этого расширяет 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);
}
}
Ответ 14
Если вы используете библиотеку каллиграфии в сочетании с 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);
Ответ 15
Возможно, странный случай, но я экспериментировал с этим и узнал, что:
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
password.setTransformationMethod(new PasswordTransformationMethod());
изменил размер шрифта подсказки вместо самого шрифта! Это по-прежнему является нежелательным эффектом. Как ни странно, обратная операция:
password.setTransformationMethod(new PasswordTransformationMethod());
password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
Сохраняет одинаковый размер шрифта.
Ответ 16
Я нашел верное решение этой проблемы
Лучший способ Привет, я нашел верное решение этой проблемы
Лучший способ - создать собственный editText и сохранить значение гарнитуры как темп, а затем применить метод к изменениям 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);
}
}
}
Ответ 17
Это как сделать пароль ввода с подсказкой, которая не была преобразована в * и шрифт по умолчанию!!.
В XML:
android:inputType="textPassword"
android:gravity="center"
android:ellipsize="start"
android:hint="Input Password !."
В действии:
inputPassword.setTypeface(Typeface.DEFAULT);
благодаря: mango и rjrjr для понимания: D.
Ответ 18
как и выше, но убедитесь, что у полей нет жирного стиля в xml, так как они никогда не будут выглядеть одинаково даже с вышеупомянутым исправлением!