如何在EditText中以不同颜色对值进行哈希标记?

时间:2018-07-24 14:09:30

标签: android android-edittext hashtag

当我写“#data” 时,我正在EditText中写一些文本,它的颜色应该改变,但不改变我该怎么做。请检查以下我使用过的EditText

<EditText
         android:id="@+id/et_simple"
         android:layout_height="wrap_content"
         android:layout_width="match_parent">
</EditText>

3 个答案:

答案 0 :(得分:4)

希望此解决方案会有所帮助..!

我用这个解决方案非常有用!例如在您的editText上添加textWatcher界面,然后侦听textChange并找出单词是否以hashTag开头,然后对该单词调用Change The color方法!它有一些缺陷,但那些是可忽略的,请在此处查看此简单的缺陷。

new

答案 1 :(得分:0)

科特林

具有自定义属性的完整解决方案

    <declare-styleable name="EditTextView">
        <attr name="enableTagging" format="boolean"/>
    </declare-styleable>
class EditTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatEditText(context, attrs, defStyleAttr) {
    private var hashtagindex = -1
    private var enableTagging:Boolean = false
        set(value) {
            field = value
            invalidate()
            requestLayout()
        }

    init {
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.EditTextView, 0, 0).apply {
                try {
                    enableTagging = getBoolean(R.styleable.EditTextView_enableTagging, false)
                } finally {
                    recycle()
                }
        }
    }


    override fun onTextChanged(text: CharSequence?, start: Int, lengthBefore: Int, lengthAfter: Int) {
        text?.let { handleTagging(text, start, lengthBefore, lengthAfter) }
    }

    private fun handleTagging(text: CharSequence, start: Int, lengthBefore: Int, lengthAfter: Int) {
        if (!enableTagging || text.length <= start) return
        if (text[start] == '#') hashtagindex = start
        if (text[start] == ' ') hashtagindex = -1
        // If hashtag then color the work
        if (hashtagindex >= 0) {
            val spannableString = getText()
            val foregroundSpan = ForegroundColorSpan(ContextCompat.getColor(context, R.color.colorPrimary))
            spannableString?.setSpan(foregroundSpan, hashtagindex, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
    }
}

这是如何为EditText启用标记

<com.example.xyz.util.editbox.EditTextView
        xmlns:custom="http://schemas.android.com/apk/res-auto"
        android:id="@+id/et"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"

        custom:enableTagging="true"

        tools:textAppearance="@style/TextAppearance.AppCompat.Moment.Date"
        tools:text="Name the "/>

编辑:

如果您删除任何字符或您的编辑文本为多行,上述机制将不起作用,以下方法应起作用:

 private fun handleTagging(text: CharSequence, start: Int, lengthBefore: Int, lengthAfter: Int) {
    if (!enableTagging || text.length <= start) return

    val formattedText = text.substring(0, start).trim();
    val lastWord =  formattedText.split(Regex("\\s+")).last()
    val tagIndex = if (lastWord.isNotEmpty() && lastWord[0] == '#') formattedText.lastIndexOf('#') else -1

    if (tagIndex >= 0) {
        val foregroundSpan = ForegroundColorSpan(ContextCompat.getColor(context, R.color.colorPrimary))
        getText()?.setSpan(foregroundSpan, tagIndex, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
    }
}

或者,如果您像我一样喜欢扩展名,可以将其重构为

fun CharSequence.getTagIndices(toIndex:Int = 0):Pair<Int, Int>? {
    val formattedText = substring(0, toIndex).trim()
    val lastWord =  formattedText.split(Regex("\\s+")).last().trim()
    if (!lastWord.startsWith('#') || lastWord.endsWith('#')) return null
    val startIndex = formattedText.lastIndexOf('#')
    val endIndex = formattedText.length - 1
    if (startIndex < 0 || endIndex < 0) return null
    return Pair(startIndex, endIndex)
}

 private fun handleTagging(text: CharSequence, start: Int, lengthBefore: Int, lengthAfter: Int) {
        if (!enableTagging || text.length <= start) return

        text.getTagIndices(start + 1)?.let {
            val foregroundSpan = ForegroundColorSpan(ContextCompat.getColor(context, R.color.colorPrimary))
            getText()?.setSpan(foregroundSpan, it.first, it.second + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
    }

答案 2 :(得分:0)

您可以轻松地使用 CodeView 库来突出显示主题标签、电子邮件或数据格式

CodeView mCodeView = findViewById(R.id.codeView);
Pattern hashTagPattern = Pattern.compile("#[a-zA-z0-9]+");
mCodeView.addSyntaxPattern(hashTagPattern, Color.BLUE);

你需要初始化它并为hashtag设置一个带有colou的图案,然后你可以在运行时更改颜色,结果将是这样的

Test hashtags

图书馆链接:https://github.com/AmrDeveloper/codeview