【问题标题】:Apply Spannable to string in string.xml through parameter通过参数将 Spannable 应用于 string.xml 中的字符串
【发布时间】:2016-06-03 12:47:13
【问题描述】:

我在string.xml中定义了以下字符串

<string name="photo_heading"><xliff:g name="name">%s</xliff:g> shared a <xliff:g name="permission">%s</xliff:g><xliff:g name="photo">%s</xliff:g> with you.</string>

String 接受 3 个字符串参数:namepermissionphoto

我有两种设置不同样式的方法。

public Spannable getStyledItalic(String text) {
        Spannable sb = new SpannableString(text);
        sb.setSpan(new StyleSpan(Typeface.ITALIC), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        return sb;
    }

public Spannable getStyledName(String name) {
        Spannable sb = new SpannableString(name);
        sb.setSpan(new AbsoluteSizeSpan(LPConstants.FONT_SIZE_NAME), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        sb.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        sb.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.color.app_primary)), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        return sb;
    }

现在我将这些样式应用于不同的参数并返回字符串,但这不起作用。这是我正在做的事情:

public String getHeading(Printrequest printRequest) {
        String name = printRequest.sentbyname;
        String permission;
        String photo;
        if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) {
            permission =  printRequest.mediaobject.permission;
        } else {
            permission = "";
        }
        if (printRequest.mediaobject.hyperphoto != null) {
            photo = " " + getStyledItalic(mContext.getString(R.string.hyperphoto));
        } else {
            photo = " " + mContext.getString(R.string.photo);
        }

        String heading = mContext.getString(R.string.photo_heading, getStyledName(name), getStyledItalic(permission), photo);

        return heading;
    }

我知道我们可以将SpannableTextUtils.concat(...) 连接起来,但我的情况不同。

解决方案

请检查以下解决方案。 @Krislarson 解决方案也是另一种方法。

【问题讨论】:

  • 感谢您的反对,但如果您能提出解决方案就更好了。
  • 使用 SpannableStringBuilder 而不是隐式 StringBuilder
  • @pskink 你能解释一下你是什么意思,因为我没有使用 StringBuilder。
  • 你正在连接两个字符串,它会清除跨度
  • @pskink 是的,但是如何在使用 getString(R.string....) 方法获取字符串时进行连接?所有的努力都是重用 getStyledItalic(String text) 和 getStyledName(String name) 方法。

标签: android xml string spannablestring


【解决方案1】:

下面是使用SpannableStringBuilder 的方法。请注意,返回类型已更改为 CharSequence 以容纳构建的 Spannable 字符串。您可以将返回值直接传递给TextView.setText()

    public CharSequence getHeading(Printrequest printRequest) {
        String name = printRequest.sentbyname;
        String permission;
        if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) {
            permission =  printRequest.mediaobject.permission;
        } else {
            permission = "";
        }

        String photoHeading = mContext.getString(R.string.photo_heading);
        SpannableStringBuilder builder = new SpannableStringBuilder(photoHeading);

        int pos = builder.toString().indexOf("%s");
        builder.replace(pos, pos+2, getStyledName(name));
        pos = builder.toString().indexOf("%s");
        builder.replace(pos, pos+2, getStyledItalic(permission));
        pos = builder.toString().indexOf("%s");
        if (printRequest.mediaobject.hyperphoto != null) {
            builder.replace(pos, pos+2, getStyledItalic(mContext.getString(R.string.hyperphoto)));
            builder.insert(pos, " ");
        } else {
            builder.replace(pos, pos+2, mContext.getString(R.string.photo));
            builder.insert(pos, " ");
        }

        return builder;
    }

【讨论】:

  • 我明白了,总之我们不能通过字符串中的标签直接应用 Spannable?
  • @Shahzeb 您可以使用TextUtils#expandTemplate 在string.xml 中使用参数,但您需要在模板中传递“^1”、“^2”等而不是“%s”跨度>
  • 你不能用Resource.getString()来做,因为它只适用于Strings,而不是CharSequences。你确实有Html.fromHtml(),它接受一个字符串并返回一个Spanned,但它只解析一组非常有限的HTML标签。事实上,我认为它可能会识别&lt;font color="[color]"&gt; 以及&lt;b&gt;&lt;i&gt; 标签,因此您可以使用Html.fromHtml() 来获取标记文本。
  • @krislarson 仅供参考,请参阅上面的评论
  • @pskink 啊。确实如此。
【解决方案2】:

我需要TextUtils.expandTemplate(...)。感谢 @pskink 的指出和 @krislarson 的努力。

<string name="photo_heading"><xliff:g name="name">^1</xliff:g> shared a<xliff:g name="permission">^2</xliff:g> <xliff:g name="photo">^3</xliff:g> with you.</string>

public CharSequence getHeading(Printrequest printRequest) {
        String name = printRequest.sentbyname;
        String permission;
        CharSequence photo;
        if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) {
            permission =  " " + printRequest.mediaobject.permission;
        } else {
            permission = "";
        }
        if (printRequest.mediaobject.hyperphoto != null) {
            photo = getStyledItalic(mContext.getString(R.string.hyperphoto));
        } else {
            photo = mContext.getString(R.string.photo);
        }

        return TextUtils.expandTemplate(mContext.getString(R.string.photo_heading), getStyledName(mContext, name), getStyledItalic(permission), photo);
    }

【讨论】:

  • 它不起作用,你不能这样做:" " + getStyledItalic(mContext.getString(R.string.hyperphoto)); 因为你的斜体跨度将被清除
  • @pskink 会更改为 CharSequence 帮助吗?实际上,我没有任何案例进入此检查,所以到目前为止它工作正常。
  • 我不这么认为,但试试看
  • 无论哪种情况,您都可以添加空格;你不能把它放在字符串里吗? ...name="permission"&gt;^2&lt;/xliff:g&gt; &lt;xliff:g name="photo"... 那你就可以去掉那个串连操作了。
  • @krislarson 我可以,但实际上许可是问题,如果它是“公开的”,我不需要显示任何其他显示许可。所以如果它是公开的,就会出现双倍空格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
相关资源
最近更新 更多