Android SpannableString使用详解

       使用TextView的过程中,有时候会需要将一串文本中的部分文字做特别的显示效果处理,比如加粗、改变颜色、加着重标识、超链接等等,我们可以通过多个TextView拼凑来实现,但如果需要特殊处理的内容在整个文本的中间,用多个TextView拼凑实在是太麻烦了,Android提供的SpannableString类能够很好地解决这个问题,SpannableString结合下面各种以Span结尾的类可以做出丰富多样的显示效果。
       这里重点要理解的是setSpan方法:

第一个参数对应的是一个相应的Span对象,比如颜色的Span对象,图片的Span对象都是不同的。
第二个参数是开始设置的字符串的游标值
第三个参数是设置末尾的字符串的游标值
第四个参数是代表一个标识,一般使用固定的就可以了。

       还有一个就是一个SpannableString对象是可以通过setSpan方法设置多个Span对象的。
       最后把SpannableString对象当成一个String字符串通过SetText方法传给TextView,就完成所有的操作了。

一.SpannableString的基本使用代码示例:

//设置Url地址连接
private void addUrlSpan() {  
    SpannableString spanString = new SpannableString("超链接");  
    URLSpan span = new URLSpan("tel:0123456789");  
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
 //设置字体背景的颜色
private void addBackColorSpan() {  
    SpannableString spanString = new SpannableString("文字背景颜色");  
    BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW);  
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
 //设置字体的颜色
private void addForeColorSpan() {  
    SpannableString spanString = new SpannableString("文字前景颜色");  
    ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);  
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
//设置字体的大小
private void addFontSpan() {  
    SpannableString spanString = new SpannableString("36号字体");  
    AbsoluteSizeSpan span = new AbsoluteSizeSpan(36);  
    spanString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
//设置字体加粗
private void addStyleSpan() {  
    SpannableString spanString = new SpannableString("BIBI");  
    StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);//加粗  
    spanString.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
 //给字体中间添加删除线
private void addStrikeSpan() {  
    SpannableString spanString = new SpannableString("删除线");  
    StrikethroughSpan span = new StrikethroughSpan();  
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
 //给字体添加下划线
private void addUnderLineSpan() {  
    SpannableString spanString = new SpannableString("下划线");  
    UnderlineSpan span = new UnderlineSpan();  
    spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
//给TextView添加图片
private void addImageSpan() {  
    SpannableString spanString = new SpannableString(" ");  
    Drawable d = getResources().getDrawable(R.drawable.ic_launcher);  
    d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());  
    ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);  
    spanString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    tv.append(spanString);  
}  
}  

上面都是比较零碎的使用,下面简单演示一个使用的示例。

二.SpannableString使用示例

程序运行效果:
s1
       上面是一个字符串,前面添加一个一个图像,中间改变一些字体的背景颜色和字体本身的颜色,最后超链接,点击超链接文本可以跳转到指定的网页。
程序设计代码:

(一)主布局文件activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.newa.MainActivity" >

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

比较简单就一个TextView。

(二)activity_web.xml超链接显示的界面的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/main_wv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="toback"
        android:text="回退网页" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:onClick="topre"
        android:text="前一网页" />
</RelativeLayout>

(三)主方法的类

package com.example.newa;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //显示的字符串
        String str = "  这是设置TextView部分文字背景颜色和前景颜色的demo!可以点击连接的地址:我的博客";
        int bstart = str.indexOf("背景");
        int bend = bstart + "背景".length();
        int fstart = str.indexOf("前景");
        int fend = fstart + "前景".length();
        int baidustart = str.indexOf("我的博客");
        int baiduend = baidustart + "我的博客".length();
        //创建SpannableString对象,要传入字符串对象
        SpannableString style = new SpannableString(str);
        //设置多个Span对象
        style.setSpan(new BackgroundColorSpan(Color.RED), bstart, bend,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        style.setSpan(new ForegroundColorSpan(Color.RED), fstart, fend,
                Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        //设置超链接Span对象的自定义设置
        style.setSpan(new ClickableSpan() {

            // 在onClick方法中,指向
            @Override
            public void onClick(View widget) {
                Log.e("TAG", "你点击到我了");
                // 页面的跳转
                Intent intent = new Intent(MainActivity.this, WebActivity.class);
                intent.putExtra("url",
                        "http://blog.csdn.net/wenzhi20102321?viewmode=list");
                startActivity(intent);
            }

        }, baidustart, baiduend, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        //找到TextView控件
        TextView tvColor = (TextView) findViewById(R.id.tv);
        // 在点击连接时,有执行的动作,都必须设置MovementMethod对象
        tvColor.setMovementMethod(LinkMovementMethod.getInstance());
        // 给TextView添加图片
        Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
        style.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//显示在字符串开始的地方
        //给TextView控件设置SpannableString对象
        tvColor.setText(style);

    }

}

(四)要跳转到的Activity页面的代码

package com.example.newa;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.URLUtil;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class WebActivity extends Activity {
    // 定义布局内的控件
    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        // 实例化控件
        webView = (WebView) findViewById(R.id.main_wv);
        toWeb();
    }

    /**
     * 跳转到网络页面
     */
    public void toWeb() {

        // 设置页面显示的URL地址
        String url = getIntent().getStringExtra("url");
        webView.loadUrl(url);


        // 一般要设置WebViewClient,才能让网页在本页面布局内显示,否则会跳转到浏览器软件打开页面
        webView.setWebViewClient(new WebViewClient() {
            // shouldOverrideUrlLoading方法return true
            // 表示我加载后这个Intent就消费了,不再跳转到其他页面。
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.e("TAG", "你点击到我了"+url);
                //重定向,不设置的话,很多网址是不能链接到的
                view.loadUrl(url);
                return true;
            }
        });
        // 取消滚动条
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        // 添加网页的文本,支持java的JavaScript显示
        // webView.loadDataWithBaseURL(null, string, null, "utf-8", null);
        // 获取WebView的设置对象,能设置是否支持缩放或是否在页面显示图片等等。
        WebSettings settings = webView.getSettings();

        // 设置是否支持缩放
        settings.setSupportZoom(false);// 有时无效!
        // 设置是否阻止显示图片
        // settings.setBlockNetworkImage(true);
        // 设置先从本地获取数据,没有的话再请求网络数据
        settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        // 设置字体的大小
        settings.setTextZoom(20);
        // 支持javaScript
        settings.setJavaScriptEnabled(true);
    }

    /**
     * 按键响应,在WebView中查看网页时,按返回键的时候按浏览历史退回,如果不做此项处理则整个WebView返回退出
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
            // 返回键退回
            webView.goBack();
            return true;// 直接返回
        }
        finish();// 关闭页面
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 回退页面
     */
    public void toback(View view) {
        if (webView.canGoBack()) {
            // 退回
            webView.goBack();
        } else {
            Toast.makeText(this, "没有能回退的页面了", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 前一个页面
     */
    public void topre(View view) {
        if (webView.canGoForward()) {
            // 前进
            webView.goForward();
        } else {
            Toast.makeText(this, "没有能前进的页面了", Toast.LENGTH_SHORT).show();
        }
    }

}

       这里使用WebView显示页面确实是有点麻烦的,但是也避免也打开其他浏览器。
       如果是要直接跳转网页,可以值主方法的类中进行简单修改就可以了:

//跳转到自带的浏览器中
Intent intent = new Intent();        
intent.setAction("android.intent.action.VIEW");    
Uri content_url = Uri.parse("http://www.cnblogs.com");   
intent.setData(content_url);    
intent.setClassName("com.android.browser","com.android.browser.BrowserActivity");   startActivity(intent);
//但是有时候它不给比跳转到你指定的网页,只是显示默认浏览器的主页!!

(五)程序运行前,还要在AndroidManifest中注册WebActivity,并且添加网络权限;

<uses-permission android:name="android.permission.INTERNET"/>
<activity android:name="com.example.newa.WebActivity" />

程序运行后的效果:
s2

点击“我的博客”文本部分,显示的界面:

s3

       上面是SpannableString在TextView中的应用,其实在EditText中应用也是比较多的,比如在输入框中添加一个表情,使用 的就是图片的Span对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值