【问题标题】:Bold words in a string of strings.xml in AndroidAndroid中strings.xml字符串中的粗体字
【发布时间】:2011-10-31 03:09:25
【问题描述】:

我在 strings.xml 的一个字符串中有一个长文本。我想加粗并更改该文本中某些单词的颜色。

我该怎么做?

【问题讨论】:

  • 您能否更具体地说明您想要实现的总体目标?

标签: java android xml


【解决方案1】:

如果要在字符串资源中使用基本的 HTML 标签,则必须对标签进行转义,否则会被忽略。 只需将 '' 和 '>' 例如:

<string name="bold_statement">This is a &lt;bold&gt; statement</string>

将产生:这是一个粗体声明。 加载字符串资源时,请务必使用

HtmlCompat.fromHtml(stringFromResource, HtmlCompat.FROM_HTML_MODE_COMPACT)

【讨论】:

    【解决方案2】:

    这是解决 string.xml 文件中是否有任何赋值的解决方案。

     <string name="styled_welcome_message"><![CDATA[We are <b> %1$s </b>  glad to see you.]]></string>
    

    设置为 TextView:

    textView?.setText(HtmlCompat.fromHtml(getString(R.string.styled_welcome_message, "sample"), HtmlCompat.FROM_HTML_MODE_LEGACY), TextView.BufferType.SPANNABLE)
    

    PS:不要忘记将您的文本(在字符串资源中)包装在:

    <![CDATA[ YOUR TEXT HERE ]]>
    

    【讨论】:

      【解决方案3】:

      如果您想将格式化存储为字符串变量并将其重用于文本视图是不可能的

      如果不应用格式,可以直接设置TextView文本 通过调用 setText(java.lang.CharSequence)。然而,在某些情况下, 您可能希望创建一个样式化的文本资源,该资源也用作格式字符串。通常,这不起作用,因为 format(String, Object...) 和 getString(int, Object...) 方法 strip 字符串中的所有样式信息。解决此问题的方法是编写带有转义实体的 HTML 标记,这些实体是 然后在格式化后使用 fromHtml(String) 恢复 地点。

      来自文档,因此可以交替存储字符串 id,并且每次使用 Htlm.fromHtml().. 方法绑定获取字符串。

      例如:

      Kotlin 扩展

      fun Context.getStringFromResource(stringId: Int): Spanned {
          return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
              Html.fromHtml(java.lang.String.format(resources.getString(stringId)), 
       Html.FROM_HTML_MODE_COMPACT)
          } else {
              Html.fromHtml(java.lang.String.format(resources.getString(stringId)))
          }
      }
      

      在代码中:

      getStringFromResource(id)
      

      【讨论】:

        【解决方案4】:

        在 Kotlin 中,我为 Context 创建了一个扩展函数。它需要一个 @StringRes 并且您也可以选择提供参数。

        fun Context.fromHtmlWithParams(@StringRes stringRes: Int, parameter : String? = null) : Spanned {
        
            val stringText = if (parameter.isNullOrEmpty()) {
                            this.getString(stringRes)
                        } else {
                            this.getString(stringRes, parameter)
                        }
        
            return Html.fromHtml(stringText, Html.FROM_HTML_MODE_LEGACY)
        
        }
        

        用法

        tv_directors.text = context?.fromHtmlWithParams(R.string.directors, movie.Director)
        

        【讨论】:

          【解决方案5】:

          字符串.xml

          <string name="sentence">This price is <b>%1$s</b> USD</string>
          

          page.java

          String successMessage = getText(R.string.message,"5.21");
          

          这个价格5.21美元

          【讨论】:

          • 您应该使用本机功能来传递参数。只需放置“%1$s”而不是“{1}”,然后调用 getString(R.string.message, "5.21") 而不使用 replace()
          • 文档支持这个答案:developer.android.com/guide/topics/resources/… 虽然它确实需要通过 HTML 解析器传递
          • 这个答案不正确。 (或至少是最后一次编辑)。 getText(int) 方法只接受一个参数 - 字符串资源 ID。 @Jemshit Iskenderov 请检查您的编辑
          • @AlexBusuioc ik,无论哪种方式都不正确,我投了反对票。如果你使用 getString,粗体格式就消失了。如果你使用 getText,参数就消失了
          • getText 不支持附加值
          【解决方案6】:

          我的文字类似于:

          忘记密码?在这里重置。

          为了实现这一点,我使用了现有的 android:textStyle="bold"

          <LinearLayout
                  android:id="@+id/forgotPassword"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:orientation="horizontal"
                  android:gravity="center"
                  >
          
          
                  <TextView
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:autoLink="all"
                      android:linksClickable="false"
                      android:selectAllOnFocus="false"
          
                      android:text="Forgot password? "
                      android:textAlignment="center"
                      android:textColor="@android:color/white"
                      />
          
                  <TextView
          
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:autoLink="all"
                      android:linksClickable="false"
                      android:selectAllOnFocus="false"
          
                      android:text="Reset here"
                      android:textAlignment="center"
                      android:textColor="@android:color/white"
                      android:textStyle="bold" />
              </LinearLayout>
          

          也许对某人有帮助

          【讨论】:

            【解决方案7】:

            字符串.xml

            <string name="my_text"><Data><![CDATA[<b>Your text</b>]]></Data></string>
            

            设置

            textView.setText(Html.fromHtml(getString(R.string.activity_completed_text)));
            

            【讨论】:

            • Html.fromHtml 已弃用
            【解决方案8】:

            在 kotlin 中,您可以在资源(活动|片段 |上下文)上创建扩展函数,将您的字符串转换为 html 跨度

            例如

            fun Resources.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()
            
            fun Resources.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()
            
            fun Resources.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = getQuantityString(id, quantity).toHtmlSpan()
            
            fun Resources.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = getQuantityString(id, quantity, *formatArgs).toHtmlSpan()
            
            fun String.toHtmlSpan(): Spanned = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
            } else {
                Html.fromHtml(this)
            }
            

            用法

            //your strings.xml
            <string name="greeting"><![CDATA[<b>Hello %s!</b><br>]]>This is newline</string>
            
            //in your fragment or activity
            resources.getHtmlSpannedString(R.string.greeting, "World")
            

            编辑更多扩展

            fun Context.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()
            
            fun Context.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()
            
            fun Context.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()
            
            fun Context.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()
            
            
            fun Activity.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()
            
            fun Activity.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()
            
            fun Activity.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()
            
            fun Activity.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()
            
            
            fun Fragment.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()
            
            fun Fragment.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()
            
            fun Fragment.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()
            
            fun Fragment.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()
            

            【讨论】:

            • @Himanshu Mori 一些 sn-p 会有所帮助。你在 kotlin 类中使用它吗?
            • Activity扩展不是必须的,Activity本身就是Context
            【解决方案9】:

            你可以从字符串中做到这一点

             <resources xmlns:tools="http://schemas.android.com/tools">
            
             <string name="total_review"><b>Total Review: </b> </string>
            
             </resources>
            

            并且可以从像

            这样的 java 代码中访问它
            proDuctReviewNumber.setText(getResources().getString(R.string.total_review)+productDetailsSuccess.getProductTotalReview());
            

            【讨论】:

              【解决方案10】:

              正如 David Olsson 所说,您可以在字符串资源中使用 HTML:

              <resource>
                  <string name="my_string">A string with <i>actual</i> <b>formatting</b>!</string>
              </resources>
              

              然后,如果您使用 getText(R.string.my_string) 而不是 getString(R.string.my_string),您将返回包含嵌入格式的 CharSequence 而不是 String

              【讨论】:

              • getText 返回 CharSequence 不是 Spannable
              • 如果您的字符串是一个需要添加数字的数量怎么办?
              • getText 不允许您使用占位符
              【解决方案11】:

              在字符串资源中使用 html 标签:-

              <resources>
              <string name="string_resource_name"><![CDATA[<b> Your text </b>]]> </string>
              </resources>
              

              并从字符串资源中获取粗体文本,例如:-

              private Spanned getSpannedText(String text) {
                      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                          return Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT);
                      } else {
                          return Html.fromHtml(text);
                      }
                  }
              
              
               String s = format(context.getResources().getString(R.string.string_resource_name));
               textView.setText(getSpannedText(s));
              

              【讨论】:

              • 这是最好的答案,它完全适用于使用 @BindingAdapter 的人。谢谢你,兄弟。
              • 它还解决了包含围绕参数的样式到字符串本身+1
              【解决方案12】:

              您基本上可以在字符串资源中使用 html 标签,例如:

              <resource>
                  <string name="styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
              </resources>
              

              并使用 Html.fromHtml 或使用 spannable,检查我发布的链接。

              老类似问题:Is it possible to have multiple styles inside a TextView?

              【讨论】:

              • 另外,根据您使用资源字符串的方式,您可能需要将粗体/斜体标记放在 CDATA 块中,以便在 Html.fromHtml() 使用之前不会对其进行解析:... &lt;![CDATA[&lt;b&gt;&lt;i&gt;so&lt;/i&gt;&lt;/b&gt;]]&gt; ...
              • 对于其他发现官方 Android 文档对此有点含糊的人:如果您在字符串资源中使用 之类的标签,请确保使用 getText(R.string.whatever) 而不是 @987654326 检索它@
              • 所以不需要Html.fromHtmlSpannable。就像提到的@andygeers 一样使用getText(R.string.whatever)
              • @andygeers 对于像“我的名字是 %s”这样不能使用 getText 因为它只接受一个参数的字符串,我们能做什么?
              • 仍然,我遇到了一个问题,在 String.xml 文件中的字符串之间使用 %1$s。 getString(v1, v2) 不能替换为 getText(v1, v2)
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-04-27
              • 2020-10-30
              • 2012-02-02
              • 1970-01-01
              • 2017-08-15
              相关资源
              最近更新 更多