package com.xscm.moduleutil.utils; import android.graphics.Color; import android.graphics.Typeface; import android.os.Build; import android.text.Html; import android.text.Spannable; import android.text.SpannableString; import android.text.method.LinkMovementMethod; import android.text.style.BackgroundColorSpan; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.UnderlineSpan; import android.view.View; import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; /** * TextView 富文本工具类(Java实现) * 支持HTML解析、部分文本样式、点击事件等功能 */ public class TextViewUtils { /** * 显示HTML格式文本 * @param textView 目标TextView * @param htmlContent HTML内容字符串 */ public static void setHtmlText(TextView textView, String htmlContent) { setHtmlText(textView, htmlContent, true); } /** * 显示HTML格式文本(可控制链接点击) * @param textView 目标TextView * @param htmlContent HTML内容字符串 * @param enableLinks 是否启用链接点击 */ public static void setHtmlText(TextView textView, String htmlContent, boolean enableLinks) { if (textView == null || htmlContent == null) return; // 处理不同Android版本的HTML解析 CharSequence spannedText; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { spannedText = Html.fromHtml(htmlContent, Html.FROM_HTML_MODE_COMPACT); } else { // 兼容Android N以下版本 spannedText = Html.fromHtml(htmlContent); } textView.setText(spannedText); // 启用链接点击功能 if (enableLinks) { textView.setMovementMethod(LinkMovementMethod.getInstance()); textView.setHighlightColor(Color.TRANSPARENT); // 去除点击高亮 } } /** * 给部分文本设置样式 * @param textView 目标TextView * @param fullText 完整文本 * @param targetText 需要设置样式的子文本 * @param spans 样式集合(可传入多个) */ public static void setPartialStyle(TextView textView, String fullText, String targetText, Object... spans) { if (textView == null || fullText == null || targetText == null) return; int startIndex = fullText.indexOf(targetText); if (startIndex == -1) { textView.setText(fullText); return; } int endIndex = startIndex + targetText.length(); SpannableString spannable = new SpannableString(fullText); // 应用所有样式 for (Object span : spans) { spannable.setSpan(span, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } textView.setText(spannable); } /** * 设置可点击文本 * @param textView 目标TextView * @param fullText 完整文本 * @param clickText 可点击的子文本 * @param linkColor 链接颜色 * @param isUnderline 是否显示下划线 * @param listener 点击事件监听器 */ public static void setClickableText(TextView textView, String fullText, String clickText, @ColorInt int linkColor, boolean isUnderline, OnClickableTextListener listener) { if (textView == null || fullText == null || clickText == null || listener == null) return; int startIndex = fullText.indexOf(clickText); if (startIndex == -1) { textView.setText(fullText); return; } int endIndex = startIndex + clickText.length(); SpannableString spannable = new SpannableString(fullText); // 创建可点击样式 ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(@NonNull View widget) { listener.onClick(); } @Override public void updateDrawState(@NonNull android.text.TextPaint ds) { super.updateDrawState(ds); ds.setColor(linkColor); ds.setUnderlineText(isUnderline); } }; spannable.setSpan(clickableSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannable); textView.setMovementMethod(LinkMovementMethod.getInstance()); textView.setHighlightColor(Color.TRANSPARENT); } // 快捷创建样式的工具方法 public static StyleSpan createBoldSpan() { return new StyleSpan(Typeface.BOLD); } public static StyleSpan createItalicSpan() { return new StyleSpan(Typeface.ITALIC); } public static ForegroundColorSpan createTextColorSpan(@ColorInt int color) { return new ForegroundColorSpan(color); } public static BackgroundColorSpan createBgColorSpan(@ColorInt int color) { return new BackgroundColorSpan(color); } public static UnderlineSpan createUnderlineSpan() { return new UnderlineSpan(); } public static StrikethroughSpan createStrikethroughSpan() { return new StrikethroughSpan(); } public static RelativeSizeSpan createTextSizeSpan(float proportion) { return new RelativeSizeSpan(proportion); } /** * 可点击文本的监听器接口 */ public interface OnClickableTextListener { void onClick(); } }