You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中获取API数据后修改HTML属性的方法

修改Html.fromHtml()渲染的HTML链接样式方案

我通过API获取到包含HTML格式文本的食谱数据,其中summary字段带有<b>和<a>标签。目前用Html.fromHtml()方法将其渲染为可样式化文本显示,但希望修改其中链接的颜色等属性。

API返回数据示例

{"id": 4632,"title": "Soy-and-Ginger-Glazed Salmon with Udon Noodles","summary": "Soy-and-Ginger-Glazed Salmon with Udon Noodles might be a good recipe to expand your main course collection. This dairy free and pescatarian recipe serves 4 and costs <b>$5.91 per serving</b>. One serving contains <b>552 calories</b>, <b>48g of protein</b>, and <b>17g of fat</b>. 1 person were impressed by this recipe. From preparation to the plate, this recipe takes roughly <b>1 hour and 35 minutes</b>. This recipe from Food and Wine requires sesame seeds, lime juice, olive oil, and salmon fillets. Taking all factors into account, this recipe <b>earns a spoonacular score of 92%</b>, which is great. If you like this recipe, take a look at these similar recipes: <a href=\"https://spoonacular.com/recipes/soy-and-ginger-glazed-salmon-with-udon-noodles-1309259\">Soy-and-Ginger-Glazed Salmon with Udon Noodles</a>, <a href=\"https://spoonacular.com/recipes/soy-and-ginger-glazed-salmon-with-udon-noodles-1360935\">Soy-and-Ginger-Glazed Salmon with Udon Noodles</a>, and <a href=\"https://spoonacular.com/recipes/soy-and-ginger-glazed-salmon-with-udon-noodles-1321839\">Soy-and-Ginger-Glazed Salmon with Udon Noodles</a>."}

当前代码实现(RecipeDetails.java)

private final RecipeDetailsListeners recipeDetailsListeners = new RecipeDetailsListeners() {
        @SuppressLint("SetTextI18n")
        @Override
        public void didFetch(RecipeDetailsResponse response, String message) {
            Picasso.get().load(response.image).into(recipeImage);
            RecipeName.setText(response.title);
            recipeSource.setText(response.sourceName);
            if (response.sourceName == null){
                recipeSource.setText("Unknown");
            }
            recipeServing.setText(response.servings + " Serving");
            recipeTimePrepared.setText(response.readyInMinutes + " Min");
            recipeScore.setText(String.valueOf(response.aggregateLikes) + " Likes");
            recipeSummary.setText(Html.fromHtml(response.summary, Html.FROM_HTML_MODE_COMPACT));

            IngredientListRecipeDetails.setHasFixedSize(true);
            IngredientListRecipeDetails.setLayoutManager(new LinearLayoutManager(getBaseContext(), LinearLayoutManager.VERTICAL, false ));
            adapter = new recipeDetailsIngredientAdapter(getBaseContext(), response.extendedIngredients);
            IngredientListRecipeDetails.setAdapter(adapter);
        }
        @Override
        public void didError(String message) {
            customToast("Unsuccessful", message, "Failure");
        }
    };

解决方案

方法1:自定义TagHandler处理a标签

实现Html.TagHandler接口,在HTML解析阶段为a标签设置自定义颜色:

public class CustomTagHandler implements Html.TagHandler {
    private int linkColor;

    public CustomTagHandler(int linkColor) {
        this.linkColor = linkColor;
    }

    @Override
    public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
        if (tag.equalsIgnoreCase("a") && !opening) {
            int start = output.length();
            int end = output.length();
            // 定位链接文本的起止位置
            while (start > 0 && output.charAt(start - 1) != '<') {
                start--;
            }
            while (end < output.length() && output.charAt(end) != '>') {
                end++;
            }
            // 设置链接颜色
            output.setSpan(new ForegroundColorSpan(linkColor), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
}

修改调用Html.fromHtml()的代码:

// 替换原有的recipeSummary.setText(...)
int customLinkColor = ContextCompat.getColor(getBaseContext(), R.color.your_custom_color);
Spanned htmlSpanned = Html.fromHtml(response.summary, Html.FROM_HTML_MODE_COMPACT, null, new CustomTagHandler(customLinkColor));
recipeSummary.setText(htmlSpanned);

方法2:直接修改HTML字符串,添加style属性

对response.summary中的a标签进行字符串替换,插入颜色样式:

String modifiedSummary = response.summary.replace("<a href=\"", "<a style=\"color:#FF5722;\" href=\"");
recipeSummary.setText(Html.fromHtml(modifiedSummary, Html.FROM_HTML_MODE_COMPACT));

注:将#FF5722替换为你需要的颜色值。

方法3:修改已渲染的Spanned对象

先获取Html.fromHtml()的渲染结果,再遍历替换其中的URLSpan样式:

Spanned originalSpanned = Html.fromHtml(response.summary, Html.FROM_HTML_MODE_COMPACT);
SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(originalSpanned);

URLSpan[] urlSpans = spannableBuilder.getSpans(0, originalSpanned.length(), URLSpan.class);
for (URLSpan urlSpan : urlSpans) {
    int start = spannableBuilder.getSpanStart(urlSpan);
    int end = spannableBuilder.getSpanEnd(urlSpan);
    spannableBuilder.removeSpan(urlSpan);
    // 创建自定义样式的URLSpan
    spannableBuilder.setSpan(new URLSpan(urlSpan.getURL()) {
        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setColor(ContextCompat.getColor(getBaseContext(), R.color.your_custom_color));
            ds.setUnderlineText(false); // 可选:去掉链接下划线
        }
    }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

recipeSummary.setText(spannableBuilder);

内容的提问来源于stack exchange,提问作者Muhammad Zarith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:39:50