Как написать стиль в текст ошибки EditText в Android?

Я пытаюсь написать новый пользовательский стиль для моего приложения для Android. Мне нужно указать стиль errorText, который появляется после установки setError в EditText.

Как я могу настроить его стиль?

Например: я хочу установить background белый и textColor: синий и т.д. в style.xml

enter image description here

Ответ 1

Решение находится в конце и вот скриншот:

Styled error


Некоторое Объяснение

может установить цвет текста, используя следующую строку

yourEditText.setError(Html.fromHtml("<font color='blue'>this is the error</font>"));

Однако это может быть не гарантировано.


В соответствии с исходным кодом этот Popup, который показывает, имеет тип ErrorPopup, который является внутренним классом внутри TextView. Содержание этого Popup - это одиночный TextView, надутый от com.android.internal.R.layout.textview_hint

final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
      null);

Фон этого Popup зависит от того, следует ли разместить его над якорем:

if (above) {
    mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error_above);
} else {
    mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error);
}

Поскольку все ресурсы android, используемые для создания всплывающих окон, являются внутренними и, в конечном счете, жестко закодированными, лучшим ударом будет создание собственного всплывающего окна. Это было бы очень просто, и вы бы действительно не вмешивались в нормальный EditText, потому что всплывающее окно по умолчанию просто используется для отображения ошибки, и, таким образом, создание вашего собственного файла будет в порядке.


Решение

Я создал его здесь: WidgyWidgets

Ответ 2

Я не думаю, что вы можете настроить свой стиль таким образом, поскольку всплывающее окно ошибки использует внутренний стиль:

mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
                    com.android.internal.R.styleable.Theme_errorMessageBackground);
mView.setBackgroundResource(mPopupInlineErrorBackgroundId);

Однако вы можете установить Spanned и значок пользовательской ошибки, используя перегруженный setError(CharSequence, Drawable).

Вы можете легко создать Spanned из HTML, используя fromHtml().

Однако вы не сможете установить всплывающее фоновое изображение: - (

Ответ 3

Пожалуйста, добавьте его во время проверки формы, если текстовое поле редактирования пуста.

            int ecolor = R.color.black; // whatever color you want
        String estring = "Please enter a valid email address";
        ForegroundColorSpan fgcspan = new ForegroundColorSpan(ecolor);
        SpannableStringBuilder ssbuilder = new SpannableStringBuilder(estring);
        ssbuilder.setSpan(fgcspan, 0, estring.length(), 0);

        edtEmail.requestFocus();
        edtEmail.setError(ssbuilder); 

когда вы пишете текст редактирования, автоматически выдается знак ошибки

Спасибо Сэчин

Ответ 4

Я видел принятый ответ, но мне не нравится предлагаемая библиотека

Я думаю, что это ошибка в платформе Android, и я подал здесь ошибку: https://code.google.com/p/android/issues/detail?id=158590

EDIT: библиотека дизайна android. Виджет TextInputLayout может использоваться для получения лучшей обработки ошибок в EditText.

Посмотрите, как это выглядит здесь: https://www.youtube.com/watch?v=YnQHb0fNtF8

И как реализовать здесь: http://code.tutsplus.com/tutorials/creating-a-login-screen-using-textinputlayout--cms-24168

Ответ 5

следуйте по этой ссылке, чтобы иметь приятный внешний вид сообщения об ошибке! materialdoc screenshot

Ответ 6

Это прекрасно!

private fun setErrorOnSearchView(searchView: SearchView, errorMessage: 
String) {
val id = searchView.context
        .resources
        .getIdentifier("android:id/search_src_text", null, null)
val editText = searchView.find<EditText>(id)

val errorColor = ContextCompat.getColor(this,R.color.red)
val fgcspan = ForegroundColorSpan(errorColor)
val builder = SpannableStringBuilder(errorMessage)
builder.setSpan(fgcspan, 0, errorMessage.length, 0)
editText.error = builder
}

Ответ 7

Я не нашел никакого решения для редактирования стиля ошибок, но я создал собственный EditText с всплывающим окном ошибки. Надеюсь, это поможет:


import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.StringRes

class ErrorEditText : EditText {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    private var errorPopup: PopupWindow? = null

    fun showError(message: String) {
        showErrorPopup(message)
    }

    fun showError(@StringRes messageResId: Int) {
        showErrorPopup(context.getString(messageResId))
    }

    fun dismissError() {
        post {errorPopup?.dismiss() }
    }

      private fun showErrorPopup(message: String) {
        post {
            dismissError()
            val inflater = (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
            val view = inflater.inflate(R.layout.edit_text_error, null, false)
            errorPopup =
                PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            errorPopup?.contentView?.findViewById<TextView>(R.id.message)?.text = message
            errorPopup?.showAsDropDown(this, 0, 10, Gravity.START)
        }
    }
}

Вы можете использовать методы: showError(message: String) или showError(@StringRes messageResId: String), чтобы показать ошибку, и метод dismissError(), чтобы скрыть ее.

Помните, что всплывающие окна связаны с жизненным циклом активности, если вы используете несколько фрагментов для навигации по приложению, не забывайте закрывать их при навигации.

Вот мой макет edit_text_error, используемый для всплывающего окна:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:elevation="2dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:background="#fff">

        <TextView
            android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#E20000"
            android:padding="8dp"
            android:textSize="11sp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            tools:text="Please enter a valid email address!" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Если вы хотите переместить всплывающее окно в конец EditText, измените последнюю строку в методе showErrorPopup() на: errorPopup?.showAsDropDown(this, 0, 10, Gravity.END)

Вы можете управлять положением всплывающего окна, изменяя параметры гравитации или x и y метода showAsDropDown(view: View, x: Int, y: Int, gravity: Gravity).