Android TextView 文本框
除了可以使用 HTML 定制 TextView 的样式外,还可以使用 SpannableString
和 SpannableStringBuilder
来完成
两者区别:前者针对的是不可变文本,而后者则是针对可变文本
SpannableString & SpannableStringBuilder 定制文本
下表列出了 SpannableString 可用的子类列表
方法 | 说明 |
---|---|
BackgroundColorSpan | 背景色 |
ClickableSpan | 文本可点击,有点击事件 |
ForegroundColorSpan | 文本颜色(前景色) |
MaskFilterSpan | 修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter) |
MetricAffectingSpan | 父类,一般不用 |
RasterizerSpan | 光栅效果 |
StrikethroughSpan | 删除线(中划线) |
SuggestionSpan | 相当于占位符 |
UnderlineSpan | 下划线 |
AbsoluteSizeSpan | 绝对大小(文本字体) |
DynamicDrawableSpan | 设置图片,基于文本基线或底部对齐。 |
ImageSpan | 图片 |
RelativeSizeSpan | 相对大小(文本字体) |
ReplacementSpan | 父类,一般不用 |
ScaleXSpan | 基于x轴缩放 |
StyleSpan | 字体样式:粗体、斜体等 |
SubscriptSpan | 下标(数学公式会用到) |
SuperscriptSpan | 上标(数学公式会用到) |
TextAppearanceSpan | 文本外貌(包括字体、大小、样式和颜色) |
TypefaceSpan | 文本字体 |
URLSpan | 文本超链接 |
范例 : 基本使用
-
创建一个 空的 Android 项目
cn.twle.android.TextView
-
下载图片 /static/i/meimei.jpg 并放到
res/drawable
目录下 -
修改
activity_main.xml
为以下内容,注意,没有设置android:text
属性<?xml version="1.0" encoding="utf-8" ?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/hello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:layout_centerInParent="true" /> </RelativeLayout>
-
修改
MainActivity.java
文件package cn.twle.android.textview; import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.method.LinkMovementMethod; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; import android.text.style.*; import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView hello = (TextView) findViewById(R.id.hello); SpannableString span = new SpannableString("红色打电话斜体删除线绿色下划线图片:."); //1. 设置背景色,setSpan 时需要指定的 flag,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE (前后都不包括) span.setSpan(new ForegroundColorSpan(Color.RED), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2. 用超链接标记文本 span.setSpan(new URLSpan("tel:4155551212"), 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //3. 用样式标记文本(斜体) span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //4. 用删除线标记文本 span.setSpan(new StrikethroughSpan(), 7, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //5. 用下划线标记文本 span.setSpan(new UnderlineSpan(), 10, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //6. 用颜色标记 span.setSpan(new ForegroundColorSpan(Color.GREEN), 10, 13,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 7. 获取 Drawable 资源 Drawable d = getResources().getDrawable(R.drawable.meimei); //左上空出一点距离 d.setBounds(16, 16, d.getIntrinsicWidth(), d.getIntrinsicHeight()); //8. 创建 ImageSpan,然后用 ImageSpan 来替换文本 ImageSpan imgspan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); span.setSpan(imgspan, 18, 19, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); hello.setText(span); // 设置点击会跳转到默认处理的 APP hello.setMovementMethod(LinkMovementMethod.getInstance()); } }
部分可点击的 TextView
部分可点击的 TextView 类似于 QQ 空间朋友对下面的点赞列表,可以点击 对应的用户然后进入查看用户相关的信息
核心其实就是设置 ClickableSpan
-
复用上面的 demo
-
下载图片 /static/i/android/good.png 并放到
res/drawable
目录下 -
修改
MainActivity.java
package cn.twle.android.textview; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.method.LinkMovementMethod; import android.text.TextPaint; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.SpannableString; import android.text.style.*; import android.view.View; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView hello = (TextView) findViewById(R.id.hello); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 20; i++) { sb.append("好友" + i + ","); } String likeUsers = sb.substring(0, sb.lastIndexOf(",")).toString(); hello.setMovementMethod(LinkMovementMethod.getInstance()); hello.setText(addClickPart(likeUsers), TextView.BufferType.SPANNABLE); } //定义一个点击每个部分文字的处理方法 private SpannableStringBuilder addClickPart(String str) { //赞的图标,这里没有素材,就找个笑脸代替下~ ImageSpan imgspan = new ImageSpan(MainActivity.this, R.drawable.good); SpannableString spanStr = new SpannableString("p"); spanStr.setSpan(imgspan, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); //创建一个SpannableStringBuilder对象,连接多个字符串 SpannableStringBuilder ssb = new SpannableStringBuilder(spanStr); ssb.append(str); String[] likeUsers = str.split(","); if (likeUsers.length > 0) { for (int i = 0; i < likeUsers.length; i++) { final String name = likeUsers[i]; final int start = str.indexOf(name) + spanStr.length(); ssb.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); //删除下划线,设置字体颜色为蓝色 ds.setColor(Color.BLUE); ds.setUnderlineText(false); } },start,start + name.length(),0); } } return ssb.append("等" + likeUsers.length + "个人觉得很赞"); } }