【问题标题】:Style text of parameter in getString(int resId, Object... formatArgs) methodgetString(int resId, Object... formatArgs) 方法中参数的样式文本
【发布时间】:2014-07-03 16:34:26
【问题描述】:

我有两个这样的字符串资源:

<string name="give_us_feedback">Give us feedback at %1$s if you want to make the app even better!</string>  
<string name="email">info@mycompany.com</string>

我想将电子邮件部分设置为蓝色并带有下划线以指示用户可以单击它(整个 TextView,而不仅仅是电子邮件文本)。我知道使用 SpannableString 为文本着色,但是当我通过 getString(int resId, Object... formatArgs) 组合两个字符串时它似乎不起作用,大概是因为 getString() 将执行强制转换或 .toString () 在被发送的对象上。以下是不起作用的:

TextView emailTV = new TextView(this);
SpannableString email = new SpannableString(getString(R.string.email));
email.setSpan(new UnderlineSpan(), 0, email.length() - 1, 0);
email.setSpan(new ForegroundColorSpan(Color.BLUE), 0, email.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
String feedback = getString(R.string.give_us_feedback, email);
emailTV.setText(feedback);

有什么想法吗?

【问题讨论】:

    标签: android string textview spannablestring


    【解决方案1】:

    这有点棘手。转换回字符序列 (String feedback = getString(R.string.give_us_feedback, email);) 会使 Spannable 消失。试试这种方式(你想检查你的字符串中的正确索引)

    String emailString = getString(R.string.email);
    String feedback = getString(R.string.give_us_feedback, emailString);
    SpannableString email = new SpannableString(feedback);
    int startIndex = feedBack.indexOf(emailString);
    int endIndex = startIndex + emailString.length();
    email.setSpan(new UnderlineSpan(), startIndex, endIndex, 0);
    email.setSpan(new ForegroundColorSpan(Color.BLUE), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    emailTV.setText(email);
    

    【讨论】:

      【解决方案2】:

      如果您的字符串已经包含与参数相同的文本,则上述答案无效。

      这就是我所做的(在 Kotlin 中)。我通过在字符串资源中搜索文字参数文本来获取参数的起始索引。这是使用正则表达式。

      val text = getString(R.string.id)
      val textWithArgs = getString(R.string.id, argument)
      
      // Searches for the start index of %1$s
      val startIndex = """%1${"\\$"}s""".toRegex().find(text)?.range?.start
      val endIndex = startIndex?.plus(argument.length)
      
      val styledText = if (startIndex == null || endIndex == null) {
          textWithArgs
      } else {
          SpannableString(textWithArgs).apply {
              setSpan(
                  ForegroundColorSpan(
                      ContextCompat.getColor(
                          context,
                          R.color.id
                      )
                  ), startIndex, endIndex, 0
              )
          }
      }
      

      【讨论】:

        【解决方案3】:

        我写了一个方法来处理它。

        isSearchForward 是一个参数,用于切换是向前还是向后搜索字符串,因为这只会突出显示第一次出现。

        private fun highlightKeywords(
            highlightColor: Int,
            message: String,
            keyword: String?,
            isSearchForward: Boolean? = true
        ): SpannableString {
            val spannableString = SpannableString(message)
            if (!keyword.isNullOrBlank()) {
                val startIndex = if (isSearchForward == true) {
                    message.indexOf(keyword)
                } else {
                    message.lastIndexOf(keyword)
                }
                val endIndex = startIndex + keyword.length
        
                spannableString.setSpan(UnderlineSpan(), startIndex, endIndex, 0)
        
                spannableString.setSpan(
                    ForegroundColorSpan(highlightColor),
                    startIndex,
                    endIndex,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
            return spannableString
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多