【问题标题】:How to hashtag value in different colour in EditText?如何在 EditText 中以不同颜色标记值?
【发布时间】:2019-01-01 04:53:16
【问题描述】:

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

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

【问题讨论】:

标签: android android-edittext hashtag


【解决方案1】:

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

我使用了这个解决方案,非常有用!就像在你的 editText 上添加 textWatcher 接口并监听 textChange 并找出单词是否以 hashTag 开头然后调用该单词的 Change The color 方法!它有一些缺陷,但这些都是可以忽略的,请看这个简单的。

Spannable mspanable;
int hashTagIsComing = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);



    final EditText edtTxtMine = (EditText) findViewById(R.id.editText1);

    mspanable = edtTxtMine.getText();

    edtTxtMine.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            String startChar = null;

            try{
                startChar = Character.toString(s.charAt(start));
                Log.i(getClass().getSimpleName(), "CHARACTER OF NEW WORD: " + startChar);
            }
            catch(Exception ex){
                startChar = "";
            }

                if (startChar.equals("#")) {
                     changeTheColor(s.toString().substring(start), start, start + count);
                     hashTagIsComing++;
                }

                if(startChar.equals(" ")){
                    hashTagIsComing = 0;
                }

                if(hashTagIsComing != 0) {
                    changeTheColor(s.toString().substring(start), start, start + count);
                    hashTagIsComing++;
                }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub

        }
    });



}


private void changeTheColor(String s, int start, int end) {
    mspanable.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.color)), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

【讨论】:

  • 当您更改光标位置并开始随机添加或删除文本或主题标签时,它会开始做一些奇怪的事情,它最终会以更改的颜色结束写入所有内容,无论是否有主题标签。
【解决方案2】:

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

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

您需要初始化它并使用colou为主题标签设置一个模式,然后您可以在运行时更改颜色,结果将是这样的

库链接:https://github.com/AmrDeveloper/codeview

【讨论】:

    【解决方案3】:

    科特林

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

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

    【讨论】:

    • EditTextView 没有获得焦点。当用户点击它时光标会闪烁,然后消失。
    【解决方案4】:

    我已经尝试了其他人提到的所有上述方法。没有任何工作正常。但它工作正常

    mSpannable = binding?.captionLayout?.etInput?.text
    
        binding?.captionLayout?.etInput?.addTextChangedListener(object : TextWatcher{
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(short_text: CharSequence, start: Int, before: Int, count: Int) {
    
                val text = binding?.captionLayout?.etInput?.text.toString()
                var last_index = 0
                text.trim().split(Regex("\\s+")).forEach {
                 
                    if (it.isNotEmpty() && it[0] == '#'){
                        //here you can style the hashtag text(I have made it bold and black)
                        val boldSpan = StyleSpan(Typeface
                            .BOLD)
                        val foregroundSpan = ForegroundColorSpan(ContextCompat.getColor(requireActivity(), R.color.black))
                        mSpannable?.setSpan(foregroundSpan, text.indexOf(it,startIndex = last_index), text.indexOf(it,startIndex = last_index)+it.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
                        mSpannable?.setSpan(boldSpan, text.indexOf(it,startIndex = last_index), text.indexOf(it,startIndex = last_index)+it.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
    
                    }
    
                    last_index+=it.length-1
    
                }
           
            }
            override fun afterTextChanged(s: Editable?) {}
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多