自定义TextView,实现图片在文字之前的富文本效果

先放一个效果图


实现这个效果,我用了两种方法 

1.第一种方法

Drawable drawable = getResources().getDrawable(图片资源);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
//这个是我自定义的适配器和viewHolder 可忽略 重点是给textView设置这个属性
((TextView) viewHolder.getView(R.id.tv_name)).setCompoundDrawables(drawable, null, null, null);
 
既然有了这种简单的方法,为什么还要自定义一个view呢 是因为我在使用的时候发现这个方法只适用于图标和文字只有一行的情况
像这样:

如果超过一行了图片整体就会居于文字的左侧 不能实现我们要的效果

2.第二种方法

第二种方法就是自定义的一个控件了  直接上图
package com.lechuang.youleduo.view.defineView;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.lechuang.youleduo.R;

/**
 * Author: guoning
 * Date: 2017/10/3
 * Description:
 */

public class SpannelTextView extends View {

    private int shopType;//店铺类型
    private Bitmap bitmap;
    private Paint paint;
    private String drawText;
    private String first, second;
    float mTextWidth;
    boolean mNewLine = false;
    private Rect rect = new Rect();
    private float scaleDenisty;

    public SpannelTextView(Context context) {
        this(context, null);
    }

    public SpannelTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SpannelTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SpannelTextView);
        shopType = typedArray.getInt(R.styleable.SpannelTextView_shopType, 1);
        drawText = typedArray.getString(R.styleable.SpannelTextView_drawText);
        typedArray.recycle();

        scaleDenisty = getResources().getDisplayMetrics().scaledDensity;

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setTextSize(12 * scaleDenisty);
        paint.setStyle(Paint.Style.FILL);

        mTextWidth = paint.measureText(drawText) * getResources().getDisplayMetrics().scaledDensity;

        //不要再onDraw中处理这一步,应该避免在onDraw中分配对象内存
        BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(shopType == 1 ? R.drawable.zhuan_taobao : R.drawable.zhuan_tmall);
        bitmap = drawable.getBitmap();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
        canvas.drawBitmap(bitmap, lp.leftMargin, lp.topMargin, paint);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        if (mNewLine) {
            paint.getTextBounds(first, 0, first.length(), rect);
            canvas.drawText(first, 3 * scaleDenisty + lp.leftMargin + bitmap.getWidth(), (3.5f * scaleDenisty + 0.5f) + lp.topMargin + (fontMetrics.descent - fontMetrics.ascent) / 2, paint);
            canvas.drawText(second, lp.leftMargin, (5f * scaleDenisty + 0.5f) + lp.topMargin + bitmap.getHeight() + (fontMetrics.descent - fontMetrics.ascent) / 2, paint);
        } else {
            canvas.drawText(drawText, 3 * scaleDenisty + lp.leftMargin + bitmap.getWidth(), (3.5f * scaleDenisty + 0.5f) + lp.topMargin + (fontMetrics.descent - fontMetrics.ascent) / 2, paint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);

        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
        if (bitmap.getWidth() + mTextWidth + lp.leftMargin + lp.rightMargin > width) {
            //换行

            for (int x = 0, length = drawText.length(); x < length; x++) {
                float v = paint.measureText(drawText.substring(0, x + 1));
                if (bitmap.getWidth() + v + lp.leftMargin + lp.rightMargin >= width) {
                    first = drawText.substring(0, x);
                    second = drawText.substring(x);
                    mNewLine = true;
                    break;
                }
            }
        }

        setMeasuredDimension(width, (int) (34 * scaleDenisty + 0.5f));
    }

    //设置文字内容
    public void setDrawText(String drawText) {
        this.drawText = drawText;
        mTextWidth = paint.measureText(drawText) * getResources().getDisplayMetrics().scaledDensity;
        invalidate();
    }
    //设置图片 这里判断服务器给我的int值 1是淘宝的icon 2是天猫
    public void setShopType(int shopType) {
        this.shopType = shopType;
        BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(shopType == 1 ? R.drawable.zhuan_taobao : R.drawable.zhuan_tmall);
        bitmap = drawable.getBitmap();
        invalidate();
    }

}

就这样


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值