48

我正在尝试为我的 android 应用程序编写新的自定义样式。setError我需要为设置后出现的 errorText 赋予样式EditText

如何自定义它的样式?

例如:我想在 style.xml 中设置它的background白色和textColor:蓝色等

在此处输入图像描述

4

7 回答 7

31

解决方案在最后,这是屏幕截图:

样式错误


一些解释

也许可以使用以下行设置 textcolor

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取决于是否应该放在anchor之上:

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

于 2013-03-07T13:28:03.883 回答
21

我认为您不能以这种方式自定义其样式,因为错误弹出窗口使用内部样式

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

但是,您可以Spanned使用重载的setError(CharSequence, Drawable).

您可以Spanned使用fromHtml().

但是,您仍然无法设置弹出背景图像 :-(

于 2013-03-05T13:47:13.967 回答
11

如果编辑文本字段为空,请在表单验证时添加。

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

当您在编辑文本中写入时,错误标志自动消失

谢谢萨钦

于 2013-04-19T06:20:44.457 回答
4

我已经看到了接受的答案,但我不喜欢建议的库

我认为这是 Android 框架中的一个错误,我在这里提交了一个错误: https ://code.google.com/p/android/issues/detail?id=158590

编辑:android 设计库 TextInputLayout 小部件可用于在 EditText 上获得更好的错误处理。

看看这里的样子: https ://www.youtube.com/watch?v=YnQHb0fNtF8

以及如何在这里实现:http: //code.tutsplus.com/tutorials/creating-a-login-screen-using-textinputlayout--cms-24168

于 2015-03-06T10:05:40.737 回答
2

按照这个链接有一个漂亮的错误信息的材料设计外观! 材料文档 截屏

我看到链接不再有效,所以这里是如何做到的: 使用TextInputLayout

<android.support.design.widget.TextInputLayout
                android:id="@+id/ipAddress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="-30dp"
                android:layout_gravity="end"
                android:digits="1234567890"
                app:errorEnabled="true" >
                <android.support.design.widget.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="end"
                    android:maxLines="1"
                    android:width="200dp"
                    android:text="@{ethernetData.ipAddress}"
                    android:enabled="@{!ethernetData.ethernetAutoIp}"/>

并在代码中TextWatcher(我使用数据绑定)调用setError你的TextInputLayout

binding.ipAddress.setError(your error);

我就是这样做的:

binding.ipAddress.getEditText().addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

            if(! Patterns.IP_ADDRESS.matcher(editable.toString()).matches()) {
                binding.ipAddress.setError(your error string);
                IpAddressOK = false;
            }
            else{
                binding.ipAddress.setError(null);
                IpAddressOK = true;
            }
        }
    });
于 2017-08-08T10:42:47.540 回答
0

这很好用!

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
}
于 2017-11-30T13:36:27.003 回答
0

我还没有找到任何编辑错误样式的解决方案,但我创建了带有错误弹出窗口的自定义 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)

您可以通过修改showAsDropDown(view: View, x: Int, y: Int, gravity: Gravity)方法的重力或x和y参数来操纵弹出窗口的位置

于 2019-05-09T11:07:25.457 回答