iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么在Android中利用SpannableString对内容进行格式化
  • 763
分享到

怎么在Android中利用SpannableString对内容进行格式化

androidspannablestringles 2023-05-31 10:05:06 763人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关怎么在Android中利用SpannableString对内容进行格式化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。要实现的效果:将话题进行变色并且可以点击提示

这篇文章将为大家详细讲解有关怎么在Android中利用SpannableString对内容进行格式化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

要实现的效果:

  1. 将话题进行变色并且可以点击提示对应的话题文本内容

  2. 将图片表情替换掉对应的表情关键字显示

  3. 将链接地址替换成一个链接的图片和”网页链接”四个字显示

  4. 将@的用户进行变色并且可以点击提示对应的话题文本内容

需要:

  1. 使用正则表达式提取文本内对应的”话题”、”表情”、”网页链接”、以及”@用户”内容

  2. 使用 SpannableString 格式化提取到的文本

  3. 给格式化的部分添加点击事件

定义正则表达式

首先定义”话题”、”表情”、”网页链接”、以及”@用户”对应的正则表达式和对应的 Pattern。SCHEME 下文会提到具体的用处的。

public class WeiboPattern { // #话题# public static final String REGEX_TOPIC = "#[\\p{Print}\\p{InCJKUnifiedIdeographs}&&[^#]]+#"; // [表情] public static final String REGEX_EMOTioN = "\\[(\\S+?)\\]"; // url public static final String REGEX_URL = "Http://[a-zA-Z0-9+&@#/%?=~_\\\\-|!:,\\\\.;]*[a-zA-Z0-9+&@#/%=~_|]"; // @人 public static final String REGEX_AT = "@[\\w\\p{InCJKUnifiedIdeographs}-]{1,26}";  public static final Pattern PATTERN_TOPIC = Pattern.compile(REGEX_TOPIC); public static final Pattern PATTERN_EMOTION = Pattern.compile(REGEX_EMOTION); public static final Pattern PATTERN_URL = Pattern.compile(REGEX_URL); public static final Pattern PATTERN_AT = Pattern.compile(REGEX_AT); public static final String SCHEME_TOPIC = "topic:"; public static final String SCHEME_URL = "url:"; public static final String SCHEME_AT = "at:";}

提取匹配部分并使用 SpannableString 格式化

我将此过程写到一个方法内了,下面直接上代码,代码中有详细的注释解释:

public static SpannableStringBuilder fORMatWeiBoContent(Context context, String source, TextView textView) { // 获取到 TextView 的文字大小,后面的 ImageSpan 需要用到该值 int textSize = (int) textView.getTextSize(); // 若要部分 SpannableString 可点击,需要如下设置 textView.setMovementMethod(LinkMovementMethod.getInstance()); // 将要格式化的 String 构建成一个 SpannableStringBuilder SpannableStringBuilder value = new SpannableStringBuilder(source); // 使用正则匹配话题 Linkify.addLinks(value, WeiboPattern.PATTERN_TOPIC, WeiboPattern.SCHEME_TOPIC); // 使用正则匹配链接 Linkify.addLinks(value, WeiboPattern.PATTERN_URL, WeiboPattern.SCHEME_URL); // 使用正则匹配@用户 Linkify.addLinks(value, WeiboPattern.PATTERN_AT, WeiboPattern.SCHEME_AT); // 自定义的匹配部分的点击效果 MyClickableSpan clickSpan; // 获取上面到所有 addLinks 后的匹配部分(这里一个匹配项被封装成了一个 URLSpan 对象) URLSpan[] urlSpans = value.getSpans(0, value.length(), URLSpan.class); // 遍历所有的 URLSpan for (final URLSpan urlSpan : urlSpans) { // 点击匹配部分效果  clickSpan = new MyClickableSpan() {   @Override   public void onClick(View view) {    ToastUtils.makeShort(urlSpan.getURL());   }  };  // 话题  if (urlSpan.getURL().startsWith(WeiboPattern.SCHEME_TOPIC)) {   int start = value.getSpanStart(urlSpan);   int end = value.getSpanEnd(urlSpan);   value.removeSpan(urlSpan);   // 格式化话题部分文本   value.setSpan(clickSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  }  // @用户  if (urlSpan.getURL().startsWith(WeiboPattern.SCHEME_AT)) {   int start = value.getSpanStart(urlSpan);   int end = value.getSpanEnd(urlSpan);   value.removeSpan(urlSpan);   // 格式化@用户部分文本   value.setSpan(clickSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  }  // 链接  if (urlSpan.getURL().startsWith(WeiboPattern.SCHEME_URL)) {   int start = value.getSpanStart(urlSpan);   int end = value.getSpanEnd(urlSpan);   value.removeSpan(urlSpan);   SpannableStringBuilder urlSpannableString = getUrlTextSpannableString(context, urlSpan.getURL(), textSize);   value.replace(start, end, urlSpannableString);   // 格式化链接部分文本   value.setSpan(clickSpan, start, start + urlSpannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  } } // 表情需要单独格式化 Matcher emotionMatcher = WeiboPattern.PATTERN_EMOTION.matcher(value); while (emotionMatcher.find()) {  String emotion = emotionMatcher.group();  int start = emotionMatcher.start();  int end = emotionMatcher.end();  int resId = EmotionUtils.getImageByName(emotion);  if (resId != -1) { // 表情匹配   L.e("find emotion: " + emotion);   Drawable drawable = context.getResources().getDrawable(resId);   drawable.setBounds(0, 0, (int) (textSize * 1.3), (int) (textSize * 1.3));   // 自定义的 VerticalImageSpan ,可解决默认的 ImageSpan 不垂直居中的问题   VerticalImageSpan imageSpan = new VerticalImageSpan(drawable);   value.setSpan(imageSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  } } return value;}
private static SpannableStringBuilder getUrlTextSpannableString(Context context, String source, int size) { SpannableStringBuilder builder = new SpannableStringBuilder(source); String prefix = " "; builder.replace(0, prefix.length(), prefix); Drawable drawable = context.getResources().getDrawable(R.drawable.ic_status_link); drawable.setBounds(0, 0, size, size); builder.setSpan(new VerticalImageSpan(drawable), prefix.length(), source.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); builder.append(" 网页链接"); return builder;}

getUrlTextSpannableString() :方法是用来返回一个图标+”网页链接” SpannableString,用于替换链接文本

上面将”话题”、”表情”、”网页链接”都用了addLinks方法来标记的,然后统一处理。表情则是单独处理的。

表情则使用如下方法事先做好映射:

public class EmotionUtils { public static LinkedHashMap<String, Integer> sMap; static {  sMap = new LinkedHashMap<>();  sMap.put("[doge]", R.drawable.d_doge);  sMap.put("[污]", R.drawable.d_wu); } public static int getImageByName(String name) {  Integer integer = sMap.get(name);  return integer == null ? -1 : integer; }}

还有刚才说到的自定义 MyClickableSpan 修改默认的样式:

public class MyClickableSpan extends ClickableSpan { @Override public void onClick(View view) { } @Override public void updateDrawState(TextPaint ds) {  super.updateDrawState(ds);  ds.setColor(0xff03A9F4);  ds.setUnderlineText(false); }}

另外,由于默认的 ImageSpan 在 TextView 有使用android:lineSpacingExtra属性时,不会垂直居中,所以使用到了网上的一个继承自 ImageSpan 的 VerticalImageSpan 可以做到保持图片在 TextView 内保持垂直居中:

public class VerticalImageSpan extends ImageSpan { public VerticalImageSpan(Drawable drawable) {  super(drawable); }  @Override public int getSize(Paint paint, CharSequence text, int start, int end,      Paint.FontMetricsInt fontMetricsInt) {  Drawable drawable = getDrawable();  Rect rect = drawable.getBounds();  if (fontMetricsInt != null) {   Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();   int fontHeight = fmPaint.descent - fmPaint.ascent;   int drHeight = rect.bottom - rect.top;   int centerY = fmPaint.ascent + fontHeight / 2;   fontMetricsInt.ascent = centerY - drHeight / 2;   fontMetricsInt.top = fontMetricsInt.ascent;   fontMetricsInt.bottom = centerY + drHeight / 2;   fontMetricsInt.descent = fontMetricsInt.bottom;  }  return rect.right; }  @Override public void draw(canvas canvas, CharSequence text, int start, int end,      float x, int top, int y, int bottom, Paint paint) {  Drawable drawable = getDrawable();  canvas.save();  Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();  int fontHeight = fmPaint.descent - fmPaint.ascent;  int centerY = y + fmPaint.descent - fontHeight / 2;  int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;  canvas.translate(x, transY);  drawable.draw(canvas);  canvas.restore(); }}

然后直接调用该方法格式化:

mTextView.setText(formatWeiBoContent(this,mTextView.getText().toString(),mTextView))

关于怎么在Android中利用SpannableString对内容进行格式化就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 怎么在Android中利用SpannableString对内容进行格式化

本文链接: https://www.lsjlt.com/news/224800.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么在Android中利用SpannableString对内容进行格式化
    这篇文章将为大家详细讲解有关怎么在Android中利用SpannableString对内容进行格式化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。要实现的效果:将话题进行变色并且可以点击提示...
    99+
    2023-05-31
    android spannablestring les
  • 怎么在Android中利用EditText对内容进行分割输入
    怎么在Android中利用EditText对内容进行分割输入?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。自定义EditTextpublic class ContentWi...
    99+
    2023-05-31
    android edittext roi
  • 怎么在Android应用中利用Bitmap对图片进行优化
    这篇文章给大家介绍怎么在Android应用中利用Bitmap对图片进行优化,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言在Android开发过程中,Bitmap往往会给开发者带来一些困扰,因为对Bitmap操作不慎...
    99+
    2023-05-31
    android roi bitmap
  • 怎么在Android中利用LeakCanary对内存泄漏进行排查
    今天就跟大家聊聊有关怎么在Android中利用LeakCanary对内存泄漏进行排查,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在 build.gralde 里加上依赖, 然后sy...
    99+
    2023-05-31
    android 内存泄漏 leakcanary
  • 怎么在Android中利用 ksoap2对WebService进行调用
    本篇文章给大家分享的是有关怎么在Android中利用 ksoap2对WebService进行调用 ,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。下载 ksoap2 的 jar ...
    99+
    2023-05-30
    ksoap2 android webservice
  • Python3中怎么对日期进行格式化
    这篇文章主要介绍“Python3中怎么对日期进行格式化”,在日常操作中,相信很多人在Python3中怎么对日期进行格式化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python3中怎么对日期进行格式化”的疑...
    99+
    2023-06-27
  • 怎么在Android中利用ClassLoader对类进行加载
    本篇文章给大家分享的是有关怎么在Android中利用ClassLoader对类进行加载,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java的类加载设计了一套双亲代理的模式,使...
    99+
    2023-05-31
    classloader android roi
  • 使用java怎么对BigDecimal进行格式化
    使用java怎么对BigDecimal进行格式化?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合...
    99+
    2023-06-14
  • 怎么在Java中利用SimpleDateFormat对英文时间格式进行转换
    这篇文章主要介绍了怎么在Java中利用SimpleDateFormat对英文时间格式进行转换,编程网小编觉得不错,现在分享给大家,也给大家做个参考,一起跟随编程网小编来看看吧!Java可以用来干什么Java主要应用于:1. web开发;2....
    99+
    2023-05-30
    java simpledateformat
  • 怎么在Android中利用 listview对数据进行显示
    怎么在Android中利用 listview对数据进行显示?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Android  listview数据显示及提示信息...
    99+
    2023-05-31
    android listview roi
  • 如何在java中调用xls对xml进行格式化
    本篇文章给大家分享的是有关如何在java中调用xls对xml进行格式化,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在java中调用xls格式化xml 使用javax.xml....
    99+
    2023-05-31
    java xls xml
  • 怎么在Android应用中利用Activity对动画进行切换
    今天就跟大家聊聊有关怎么在Android应用中利用Activity对动画进行切换,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android Activity切换动画Android ...
    99+
    2023-05-31
    android activity roi
  • 怎么在Android利用Matrix对图片进行旋转
    本篇文章给大家分享的是有关怎么在Android利用Matrix对图片进行旋转,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。自定义一个View,用来控制这两个图片的旋转。com....
    99+
    2023-05-31
    android matrix roi
  • 如何在Android应用中利用apk插件对内存进行释放
    这期内容当中小编将会给大家带来有关如何在Android应用中利用apk插件对内存进行释放,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Android apk 插件启动内存释放问题插件中启动apk,一般情况...
    99+
    2023-05-31
    android apk roi
  • 怎么在Android中利用activity与view对滑动进行判断
    这篇文章给大家介绍怎么在Android中利用activity与view对滑动进行判断,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Android activity和view判断滑动//手指按下的点为(x1, y1)手指...
    99+
    2023-05-31
    android activity view
  • 怎么在Android 开发中利用TextView对文字进行加粗
    这篇文章将为大家详细讲解有关怎么在Android 开发中利用TextView对文字进行加粗,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。首先自定义一个StyleSpan,在StyleSpan...
    99+
    2023-05-31
    android textview roi
  • SpringBoot怎么对LocalDateTime进行格式化并解析
    这篇“SpringBoot怎么对LocalDateTime进行格式化并解析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Sp...
    99+
    2023-07-02
  • 如何在Android 中利用ScrollView对GridView进行嵌套
    本篇文章为大家展示了如何在Android 中利用ScrollView对GridView进行嵌套,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Android 中ScrollView嵌套GridView...
    99+
    2023-05-31
    android scrollview gridview
  • 在Linux系统怎么正确的对U盘进行格式化
    这篇文章主要介绍了在Linux系统怎么正确的对U盘进行格式化,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在Linux操作系统中如何对U盘进行格式化:在Linux操作系统中对...
    99+
    2023-06-16
  • 怎么在Android中利用videoview对抢占的焦点进行处理
    这篇文章给大家介绍怎么在Android中利用videoview对抢占的焦点进行处理,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。问题描述:android 机顶盒应用:应用程序主界面(MainActivity)只有两个控...
    99+
    2023-05-31
    android videoview roi
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作