android图文混排&点击事件

图文混排顾名思义就是把文字和图片混合排列在一起,比较简单的需求我们也可以通过TextView和ImageView配合使用来达到目的,但是遇到稍微复杂一些的情况这种方法就不适用了。

做这样一个按钮:


android图文混排&点击事件_第1张图片

对于你来说没有任何难度:LinearLayout+TextView+ImageView搞定;或者可以直接使用TextView的drawableLeft属性。

这里记录两种复杂情况的处理方法:

  1. 部分文字添加点击事件;
  2. 图文混排,图片居中,图片可点击。

1. 为部分文字添加点击事件

我最终实现的效果是这个样子的:

android图文混排&点击事件_第2张图片

可点击文字显示为特殊颜色,并可以点击。个人觉得这个最大的特色就是可以像普通文本一样换行,这是组合控件所不能实现的。

这里使用了SpannableString和ClickableSpan实现,具体代码如下:

ClickSpan继承自ClickableSpan:

import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.View;

import com.travis.uqmei.utils.ToastUtil;

/**
 * Created by travis on 16/9/18.
 */

public class ClickSpan extends ClickableSpan {
    private String txt;

    public ClickSpan(String txt){
        this.txt = txt;
    }
    @Override
    public void onClick(View widget) {
        String content = String.format("ClickSpan is clicked, and txt is %s ",txt);
        ToastUtil.show(content);
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        //根据自己的需求定制文本的样式
        ds.setColor(ds.linkColor);
        ds.setUnderlineText(false);
    }
}

为TextView设置部分文字可点击效果:

    TextView tv = (TextView) findViewById(R.id.tv);

    String from = "张全蛋";
    String to = "赵铁柱";
    String txt = String.format("%s回复@%s:我是富士康3号流水线的张全蛋," +
          "英文名叫Micheal Jack,发文名叫helodie Jaqueline。", from, to);

    SpannableString span = new SpannableString(txt);
    ClickSpan clickSpan = new ClickSpan(to);
    span.setSpan(clickSpan, txt.indexOf(to),
            txt.indexOf(to) + to.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    tv.setText(span);
    tv.setMovementMethod(LinkMovementMethod
            .getInstance());

2. 图文混排,图片居中,图片可点击

效果如下:

android图文混排&点击事件_第3张图片

可点击效果通过上述ClickSpan实现,图文混排通过VerticalImageSapn实现。

VerticalImageSpan继承自ImageSpan:

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.style.ImageSpan;

   /**
     * 垂直居中的ImageSpan
     *
     * @author travis
     */
    public class VerticalImageSpan extends ImageSpan {

        public VerticalImageSpan(Drawable drawable) {
            super(drawable);
        }

        public int getSize(Paint paint, CharSequence text, int start, int end,
                           Paint.FontMetricsInt fontMetricsInt) {
            Drawable drawable = getDrawable();
            Rect rect = drawable.getBounds();
            if (fontMetricsInt != null) {
                Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
                int fontHeight = fmPaint.bottom - fmPaint.top;
                int drHeight = rect.bottom - rect.top;

                int top = drHeight / 2 - fontHeight / 4;
                int bottom = drHeight / 2 + fontHeight / 4;

                fontMetricsInt.ascent = -bottom;
                fontMetricsInt.top = -bottom;
                fontMetricsInt.bottom = top;
                fontMetricsInt.descent = top;
            }
            return rect.right;
        }

        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end,
                         float x, int top, int y, int bottom, Paint paint) {
            Drawable drawable = getDrawable();
            canvas.save();
            int transY = 0;
            transY = ((bottom - top) - drawable.getBounds().bottom) / 2 + top;
            canvas.translate(x, transY);
            drawable.draw(canvas);
            canvas.restore();
        }
    }

代码设置:

TextView tv = (TextView) findViewById(R.id.tv);

        String icon = "icon";
        String from = "张全蛋"+icon;
        String to = "赵铁柱";
        String txt = String.format("%s回复@%s:我是富士康3号流水线的张全蛋," +
                "英文名叫Micheal Jack,发文名叫helodie Jaqueline。", from, to);

        //设置ClickSpan,为部分文字("icon")添加点击效果
        SpannableString span = new SpannableString(txt);
        ClickSpan clickSpan = new ClickSpan(icon);
        span.setSpan(clickSpan, txt.indexOf(icon),
                txt.indexOf(icon) + icon.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        //设置ImageSpan,占用可点击文字("icon")的位置
        Bitmap bitmap = ImageUtils.resize(BitmapFactory.decodeResource(getResources(),
                R.mipmap.uqmei_icon_contact), DensityUtil.sp2px(this, 12f));
        BitmapDrawable drawable = new BitmapDrawable(bitmap);
        drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
        span.setSpan(new VerticalImageSpan(drawable),
                txt.indexOf(icon), txt.indexOf(icon) + icon.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        //设置TextView
        tv.setText(span);
        tv.setHighlightColor(Color.TRANSPARENT);//消除点击时的背景色
        tv.setMovementMethod(LinkMovementMethod.getInstance());

你可能感兴趣的:(android图文混排&点击事件)