android TextView部分文字可点击 不同大小文字添加背景且居中显示

关于SpannableString与SpannableStringBuilder更多可点击:
https://www.jianshu.com/p/84067ad289d2
http://blog.csdn.net/harvic880925/article/details/38984705
修改默认点击事件:http://dingbuoyi.iteye.com/blog/1553464

这里写图片描述

txt.setText("这是一条测试文本");
        SpannableString clickString = new SpannableString("可点击文本");
        clickString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                startActivity(new Intent(MainActivity.this, FirstActivity.class));
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.RED);//设置颜色
            }
        }, 0, clickString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        txt.append(clickString);
        txt.append(new SpannableString("这也是一条测试文本"));
        SpannableString clickString2 = new SpannableString("我是可点击的");
        clickString2.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                startActivity(new Intent(MainActivity.this, SecondActivity.class));
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.BLUE); //设置颜色
            }
        }, 0, clickString2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        txt.append(clickString2);
        txt.setMovementMethod(LinkMovementMethod.getInstance());//开始响应点击事件

不同大小文字添加背景且居中显示

参考:
https://www.jianshu.com/p/dd4286389b7e
https://www.jianshu.com/p/d7ffa436d664

要实现的效果如下
在这里插入图片描述
想要实现上图的效果首先想到的是先设置RelativeSizeSpan改变文字大小、再设置BackgroundColorSpan添加背景、再设置ForegroundColorSpan改变活动标签文字大小

SpannableString spannableString = new SpannableString(" 活动标签 " + "我是商品标题我是商品标题我是商品标题我是商品标题我是商品标题");
spannableString.setSpan(new RelativeSizeSpan(0.7f),0,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new BackgroundColorSpan(Color.RED),0,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ForegroundColorSpan(Color.WHITE),0,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvSpan.setText(spannableString);

看下结果吧
在这里插入图片描述
发现活动标签的文字没有竖直居中,这里就需要自定义了

/**
 * Created by cys on 2018/11/2 0002.
 * 根据大小绘制对应大小背景span
 */
public class BackgroundColorResizeSpan extends ReplacementSpan {
    private int mBackgroundColor;//字体背景色
    private float fontSizePx;//字体大小单位px
    private int mTextColor;//字体颜色
    private int mWidth;

    public BackgroundColorResizeSpan(int mBackgroundColor, int mTextColor, float fontSizePx) {
        this.mBackgroundColor = mBackgroundColor;
        this.mTextColor = mTextColor;
        this.fontSizePx = fontSizePx;
    }

    @Override
    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
        paint.setTextSize(fontSizePx);
        //获取文字宽度
        mWidth = (int) paint.measureText(text.subSequence(start, end).toString());
        return mWidth;
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
        paint.setTextSize(fontSizePx);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        paint.setColor(mBackgroundColor);
        //绘制背景
        canvas.drawRect(x, (bottom + top) / 2 - (fontMetrics.bottom - fontMetrics.top) / 2, mWidth, (bottom + top) / 2 + (fontMetrics.bottom - fontMetrics.top) / 2, paint);
        paint.setColor(mTextColor);
        //绘制文字
        canvas.drawText(text.subSequence(start, end).toString(), x, (top + bottom)/2 - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top, paint);

    }
}

使用起来也是比较方便的

SpannableString spannableString = new SpannableString(" 活动标签 " + "我是商品标题我是商品标题我是商品标题我是商品标题我是商品标题");
spannableString.setSpan(new BackgroundColorResizeSpan(Color.RED, Color.WHITE, spToPx(11)), 0, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvSpan.setText(spannableString);

运行出来就是第一张图的效果,里面绘制位置的计算主要用到了Paint.FontMetrics类,可参考我另一篇博客 https://blog.csdn.net/SS_S1gn/article/details/80480469 此处不再赘述

textview设置html文本,拦截超链接应用内处理

textView1.setText(Html.fromHtml(htmlLinkText));
        textView1.setMovementMethod(LinkMovementMethod.getInstance());
        CharSequence text = textView1.getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) textView1.getText();
            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            SpannableStringBuilder style = new SpannableStringBuilder(text);
            style.clearSpans();// should clear old spans

            //循环把链接发过去
            for (URLSpan url : urls) {
                MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
                style.setSpan(myURLSpan, sp.getSpanStart(url),
                        sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
            }
            textView1.setText(style);
        }
	private class MyURLSpan extends ClickableSpan {

        private String mUrl;

        MyURLSpan(String url) {
            mUrl = url;
        }

        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, mUrl, Toast.LENGTH_LONG).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);
        }
    }
你可以通过以下步骤来实现: 1. 在 res/values 目录下创建一个名为 styles.xml 的文件,并添加以下代码: ``` <style name="TransparentDialog" parent="Theme.AppCompat.Dialog"> <item name="android:background">@android:color/transparent</item> <item name="android:windowBackground">@android:color/transparent</item> </style> ``` 这个样式将会使弹窗背景透明。 2. 创建一个自定义布局文件 dialog_layout.xml,添加以下代码: ``` <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="200dp" android:layout_height="wrap_content" android:background="@drawable/dialog_bg" android:padding="16dp"> <TextView android:id="@+id/dialog_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="18sp" android:maxLines="2" android:ellipsize="end" android:gravity="center"/> </FrameLayout> ``` 其中,drawable/dialog_bg 是自定义的背景图片,你可以根据自己的需要修改。此外,这个布局将会显示一个 TextView,用于显示弹窗中的文字内容。 3. 在 Activity 中使用以下代码显示弹窗: ``` Dialog dialog = new Dialog(this, R.style.TransparentDialog); dialog.setContentView(R.layout.dialog_layout); TextView dialogText = dialog.findViewById(R.id.dialog_text); dialogText.setText("你要显示文字"); Window window = dialog.getWindow(); if (window != null) { window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); window.setGravity(Gravity.CENTER); window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } dialog.show(); dialog.findViewById(android.R.id.content).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); ``` 这里创建了一个 Dialog 对象,并设置其样式为之前定义的 TransparentDialog。然后将自定义的布局文件 dialog_layout.xml 设置为其内容视图,并找到其中的 TextView 控件并设置其文字内容。接着设置窗口的大小和位置,并将背景设置为透明。最后显示弹窗,并设置点击空白区域关闭弹窗的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值