SpannableString实现图文混排和多种炫酷样式的TextView

Android UI 专栏收录该内容
3 篇文章 0 订阅

之前项目中有一个类似贴吧的圈子,需要实现图文混排和一些特殊样式的文本,后来发现一篇不错的文章,看了之后感觉受益良多,推荐给大家:
用SpannableString打造绚丽多彩的文本显示效果

为了学习,我也照着这位朋友的demo写了一遍,在此记录下来供以后巩固使用.

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    private TextView nameTv;
    private TextView blogTv;
    private TextView intentTv;
    private TextView beforeTv;
    private TextView afterTv;
    private TextView formulaTv;
    private TextView formulaTv2;
    private TextView jumpTv;
    private TextView imgTv;

    private int position=0;
    private String jumpStr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    /**
     * 初始化View
     */
    private void initView(){

        //设置自定义样式
        nameTv=(TextView)findViewById(R.id.tv_name);//获取控件
        String nameStr=nameTv.getText().toString();//获取TextView显示的内容
        SpannableString spannableStringName=new SpannableString(nameStr);//实例化SpannableString对象
        //设置前景色(字体颜色)
        ForegroundColorSpan foregroundColorSpanName=new ForegroundColorSpan(Color.parseColor("#00B2EE"));//实例化ForegroundColorSpan对象并设置前景色
        spannableStringName.setSpan(foregroundColorSpanName,6,nameStr.length()-1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);//设置字体颜色
        //设置字体大小
        RelativeSizeSpan relativeSizeSpanName=new RelativeSizeSpan(1.5f);
        spannableStringName.setSpan(relativeSizeSpanName,6,nameStr.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        //设置字体样式
        StyleSpan styleSpanName=new StyleSpan(Typeface.BOLD);
        spannableStringName.setSpan(styleSpanName,6,nameStr.length()-1,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        nameTv.setText(spannableStringName);


        //设置超链接
        blogTv=(TextView)findViewById(R.id.tv_blog);
        String blogStr=blogTv.getText().toString();
        SpannableString spannableStringBlog=new SpannableString(blogStr);
        URLSpan urlSpan=new URLSpan("http://blog.csdn.net/zhangxmu");
        spannableStringBlog.setSpan(urlSpan,9,blogStr.length(),Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        ForegroundColorSpan foregroundColorSpanBlog=new ForegroundColorSpan(Color.parseColor("#EE1289"));
        spannableStringBlog.setSpan(foregroundColorSpanBlog,9,blogStr.length(),Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        blogTv.setText(spannableStringBlog);
        blogTv.setMovementMethod(LinkMovementMethod.getInstance());


        //自定义跳转
        intentTv=(TextView)findViewById(R.id.tv_intent);
        String intentStr=intentTv.getText().toString();
        SpannableString spannableStringIntent=new SpannableString(intentStr);
        ClickableSpan clickableSpanIntent=new MyClickableSpan("Hello Android!");
        spannableStringIntent.setSpan(clickableSpanIntent,2,intentStr.length()-4,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ForegroundColorSpan foregroundColorSpanIntent=new ForegroundColorSpan(Color.parseColor("#FFFFFF"));
        spannableStringIntent.setSpan(foregroundColorSpanIntent,2,intentStr.length()-4,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        BackgroundColorSpan backgroundColorSpanIntent=new BackgroundColorSpan(Color.parseColor("#66CD00"));
        spannableStringIntent.setSpan(backgroundColorSpanIntent,2,intentStr.length()-4,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        intentTv.setText(spannableStringIntent);
        intentTv.setMovementMethod(LinkMovementMethod.getInstance());


        //删除线
        beforeTv=(TextView)findViewById(R.id.tv_before);
        afterTv=(TextView)findViewById(R.id.tv_after);
        String beforeStr=beforeTv.getText().toString();
        String afterStr=afterTv.getText().toString();

        SpannableString spannableStringBefore=new SpannableString(beforeStr);
        SpannableString spannableStringAfter=new SpannableString(afterStr);

        StrikethroughSpan strikethroughSpan=new StrikethroughSpan();
        spannableStringBefore.setSpan(strikethroughSpan,1,beforeStr.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        ForegroundColorSpan foregroundColorSpanAfter=new ForegroundColorSpan(Color.parseColor("#EE2C2C"));
        spannableStringAfter.setSpan(foregroundColorSpanAfter,0,afterStr.length(),Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        RelativeSizeSpan relativeSizeSpanAfter=new RelativeSizeSpan(1.3f);
        spannableStringAfter.setSpan(relativeSizeSpanAfter,0,afterStr.length(),Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        StyleSpan styleSpanAfter=new StyleSpan(Typeface.ITALIC);
        spannableStringAfter.setSpan(styleSpanAfter,1,afterStr.length(),Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        beforeTv.setText(spannableStringBefore);
        afterTv.setText(spannableStringAfter);


        //上标
        formulaTv=(TextView)findViewById(R.id.tv_formula);
        formulaTv.setTextSize(18);
        String formulaStr=formulaTv.getText().toString();
        SpannableString spannableStringFormula=new SpannableString(formulaStr);
        SuperscriptSpan superscriptSpanX=new SuperscriptSpan();
        SuperscriptSpan superscriptSpanY=new SuperscriptSpan();
        spannableStringFormula.setSpan(superscriptSpanX,1,2,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableStringFormula.setSpan(superscriptSpanY,4,5,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        RelativeSizeSpan relativeSizeSpanX=new RelativeSizeSpan(0.6f);
        RelativeSizeSpan relativeSizeSpanY=new RelativeSizeSpan(0.6f);
        spannableStringFormula.setSpan(relativeSizeSpanX,1,2,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableStringFormula.setSpan(relativeSizeSpanY,4,5,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        formulaTv.setText(spannableStringFormula);

        //下标
        formulaTv2=(TextView)findViewById(R.id.tv_formula2);
        formulaTv2.setTextSize(18);
        String formulaStr2=formulaTv2.getText().toString();
        SpannableString spannableStringFormula2=new SpannableString(formulaStr2);
        SubscriptSpan subscriptSpanA=new SubscriptSpan();
        SubscriptSpan subscriptSpanB=new SubscriptSpan();
        spannableStringFormula2.setSpan(subscriptSpanA,3,4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        spannableStringFormula2.setSpan(subscriptSpanB,6,7,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        RelativeSizeSpan relativeSizeSpanA=new RelativeSizeSpan(0.5f);
        RelativeSizeSpan relativeSizeSpanB=new RelativeSizeSpan(0.5f);
        spannableStringFormula2.setSpan(relativeSizeSpanA,3,4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        spannableStringFormula2.setSpan(relativeSizeSpanB,6,7,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        formulaTv2.setText(spannableStringFormula2);


        //跳动的文本
        jumpTv=(TextView)findViewById(R.id.tv_jump);
        jumpStr=jumpTv.getText().toString();
        handler.sendEmptyMessage(0);


        //带图片的文本
        imgTv=(TextView)findViewById(R.id.tv_img);
        String imgStr=imgTv.getText().toString();
        SpannableString spannableStringImg=new SpannableString(imgStr);
        Drawable drawable=getResources().getDrawable(R.mipmap.i01);
        drawable.setBounds(0,0,(int)getResources().getDimension(R.dimen.dimen_40),(int)getResources().getDimension(R.dimen.dimen_40));
        ImageSpan imageSpan=new ImageSpan(drawable);
        spannableStringImg.setSpan(imageSpan,2,6,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        imgTv.setText(spannableStringImg);
    }

    class MyClickableSpan extends ClickableSpan{

        private String content;

        public MyClickableSpan(String content){
            this.content=content;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);//去掉下划线
        }

        @Override
        public void onClick(View view) {
            Intent intent=new Intent(MainActivity.this,SecondActivity.class);
            Bundle bundle=new Bundle();
            bundle.putString("content",content);
            intent.putExtra("bundle",bundle);
            startActivity(intent);
        }
    }

    Handler handler=new Handler(){

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    SpannableString spannableStringJump=new SpannableString(jumpStr);
                    RelativeSizeSpan relativeSizeSpanJump=new RelativeSizeSpan(1.5f);
                    spannableStringJump.setSpan(relativeSizeSpanJump,position,position+1,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                    ForegroundColorSpan foregroundColorSpanJump=new ForegroundColorSpan(Color.parseColor("#FF4040"));
                    spannableStringJump.setSpan(foregroundColorSpanJump,position,position+1,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                    jumpTv.setText(spannableStringJump);
                    position++;
                    if(position>=jumpStr.length()){
                        position=0;
                    }
                    handler.sendEmptyMessageDelayed(0,150);
                    break;
            }
        }
    };
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/lightgray"
    android:orientation="vertical"
    tools:context="com.grr.spannabledemo.MainActivity">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
               android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="Hello,GRR!" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_blog"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="我的CSDN博客:http://blog.csdn.net/zhangxmu" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_intent"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="点击绿色背景的文字进行跳转" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_before"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="$300" />

                <TextView
                    android:id="@+id/tv_after"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_toRightOf="@+id/tv_before"
                    android:gravity="center"
                    android:text="$200" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_formula"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="ax+by=c" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_formula2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="y=a2+b2" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_jump"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="双12活动火爆来袭!支付宝全场5折!" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_margin="5dp"
                android:background="@android:color/white">

                <TextView
                    android:id="@+id/tv_img"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:text="来啊(图片)互相伤害啊"
                    android:textSize="40dp" />
            </RelativeLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>


效果图(倒数第二个是会动的,此处就放了一个静态图,想看效果的话下面有代码下载地址):




完整Demo下载地址:点击下载源码


  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值