zoukankan      html  css  js  c++  java
  • android文本排布

      首先看一幅图,是简书App的一篇文章的截图,如下:

    图1,图2

    上面两个图片都是文本的显示,但是由于有多种格式,所以较为复杂,例如其中有普通文本,还有加粗的文本,还有图文混排的显示等等。

    一、解析HTML标签:

      Android的SDK提供了可以解析HTML标签进行特殊显示的方式。就是使用android.text包下的Html类来解析文本。该类可以对常用的HTML标签进行解析,然后给TextView控件进行显示。有两类标签比较特殊:

      1、链接类标签即a标签。使用该标签需要注意:

        !!!注意①需要开启网络权限②在href属性指定链接时必须添加http://,否则不能正确解析。③需要调用TextView控件的setMovementMethod方法传入点击后的行为,对连接通常使用系统自带的LinkMovementMethod即可,可以通过该类的getInstance()获取一个单例使用。

      2、图片类即img标签。使用该标签需要注意:

        注意:①需要使用fromHtml()有三个参数的重载,主要是第二个参数Html.ImageGetter的实例来进行图片的加载。

      下面是简单的演示代码,可以在TextView中展示普通文本,粗体文本<b>,链接<a>,图片<img>等:

     1    private void beforeInit(final TextView tv) {
     2         String text="哈哈,这是一个<b>富文本显示</b>的示例,例如显示网址<a href='http://www.baidu.com'>百度</a>。还可以显示一幅图片<img src='loading'>";
     3         tv.setMovementMethod(LinkMovementMethod.getInstance());
     4         tv.setText(Html.fromHtml(text, new Html.ImageGetter() {
     5             @Override
     6             public Drawable getDrawable(String source) {
     7                 Drawable drawable = null;
     8               try {
     9                   Field field = R.drawable.class.getField(source);
    10                   int resourceId = Integer.parseInt(field.get(null).toString());
    11                   drawable = getResources().getDrawable(resourceId);
    12                   drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    13               }catch (Exception e) {
    14                     e.printStackTrace();
    15                 }
    16                 return drawable;
    17             }
    18         }, null));
    19     }
    富文本示例

    二、原理解析:

      其实,在TextView显示文本时,是将该段文本当做Spanned区块来看待的,例如链接可以就是URL区块,图片就是image区块等。通过Html.fromHtml()可以对文本进行解析,然后读取不同的区块并为其进行不同的操作。我们可以看一下该方法的返回值

    1     public static Spanned fromHtml(String source, ImageGetter imageGetter,
    2                                    TagHandler tagHandler) {

      这里也可以对上面的一些问题进行说明:

      1、为什么指定链接时需要加上http://?因为在使用了LinkMovementMethod的默认行为之后,其动作就是发送一个Intent,data就是该链接的href属性所以需要通过http://来匹配可以处理该data的Activity,如果没有的话找不到Activity则会报错crash掉程序

      2、为什么图片的显示需要特殊的处理(即使用Html.ImageGetter)?因为图片文本解析出来只是普通的文本,真正显示图片需要从本地或者网络进行加载,通过实现该类的方法,指定图片加载的方式才能正确显示图片。

    三、使用SpannableString&SpannableStringBuilder来显示文本

      上面是对一段HTML文本的解析显示,已经可以满足一些要求了,但是如果不是HTML特定标签也需要特殊的显示格式该如何处理呢?例如图2中的显示特殊颜色的可点击进入特定用户的信息界面的效果的实现。这时就可以使用标题中介绍的两种方式了,这里以SpannableString为例:

      1、二中说到,TextView显示的是一个个区块,而该类就是将文本的一部分设置成特殊的区块,所有可实现的区块类型都对应android.text.style中的一个类。如下:

      • BackgroundColorSpan 背景色
      • ClickableSpan 文本可点击,有点击事件
      • ForegroundColorSpan 文本颜色(前景色)
      • MaskFilterSpan 修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)
      • MetricAffectingSpan 父类,一般不用
      • RasterizerSpan 光栅效果
      • StrikethroughSpan 删除线(中划线)
      • SuggestionSpan 相当于占位符
      • UnderlineSpan 下划线
      • AbsoluteSizeSpan 绝对大小(文本字体)
      • DynamicDrawableSpan 设置图片,基于文本基线或底部对齐。
      • ImageSpan 图片
      • RelativeSizeSpan 相对大小(文本字体)
      • ReplacementSpan 父类,一般不用
      • ScaleXSpan 基于x轴缩放
      • StyleSpan 字体样式:粗体、斜体等
      • SubscriptSpan 下标(数学公式会用到)
      • SuperscriptSpan 上标(数学公式会用到)
      • TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)
      • TypefaceSpan 文本字体
      • URLSpan 文本超链接
     1 public class MainActivity extends AppCompatActivity {
     2 
     3     @Override
     4     protected void onCreate(Bundle savedInstanceState) {
     5         super.onCreate(savedInstanceState);
     6         setContentView(R.layout.activity_main);
     7         TextView t1 = (TextView) findViewById(R.id.txtOne);
     8         TextView t2 = (TextView) findViewById(R.id.txtTwo);
     9 
    10         SpannableString span = new SpannableString("红色打电话斜体删除线绿色下划线图片:.");
    11         //1.设置背景色,setSpan时需要指定的flag,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)
    12         span.setSpan(new ForegroundColorSpan(Color.RED), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    13         //2.用超链接标记文本
    14         span.setSpan(new URLSpan("tel:4155551212"), 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    15         //3.用样式标记文本(斜体)
    16         span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    17         //4.用删除线标记文本
    18         span.setSpan(new StrikethroughSpan(), 7, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    19         //5.用下划线标记文本
    20         span.setSpan(new UnderlineSpan(), 10, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    21         //6.用颜色标记
    22         span.setSpan(new ForegroundColorSpan(Color.GREEN), 10, 13,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    23         //7.//获取Drawable资源
    24         Drawable d = getResources().getDrawable(R.drawable.icon);
    25         d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
    26         //8.创建ImageSpan,然后用ImageSpan来替换文本
    27         ImageSpan imgspan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
    28         span.setSpan(imgspan, 18, 19, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    29         t1.setText(span);
    30     }
    31 }
    SpannableString的简单使用

    效果图如下:

      最后在说一下,对于开始提出的效果的两种实现:

      1、使用URLSpan,其参数就是Intent中data的值,相当于和上面的链接一样的效果,本质上是使用隐式Intent

      2、使用ClickableSpan:实现时需要完成几个回调方法,用于在点击时进行回调。

    参考:http://www.runoob.com/w3cnote/android-tutorial-textview.html

    还有一些开源的富文本显示的框架,这里介绍一个项目:https://github.com/zzhoujay/RichText

  • 相关阅读:
    领域驱动设计学习笔记
    Entity Framework 入门
    2019秋招复习笔记--面试经历记录总结
    Windows10 系统更新之后找不到输入法
    jumper-server-部署官网版
    docker java环境 直接做成镜像 跑自己的java包
    联想thinkpad如何关闭触摸板
    docker 安装
    阿里yum源与华为yum源的配置
    Backbone简介
  • 原文地址:https://www.cnblogs.com/songfeilong2325/p/5553861.html
Copyright © 2011-2022 走看看