自定义view系列-view的多行绘制

192 阅读3分钟

1.多行绘制

其实里面就一个核心方法.

package com.xm.wanapp.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import com.xm.wanapp.R;

public class TextMultiDrawView extends View {

    private Paint mPaint;
    private TextPaint mTextPaint;
    private String text = "澳大利亚曾质疑过日本科研捕鲸的真实性。2010年,澳大利亚政府曾向海牙国际法院提起诉讼,控告日本在南冰洋的“科研”捕鲸活动实则是商业捕鲸。2014年,国际法院对此作出终审裁决,认定日本“出于科研目的”的捕鲸理由不成立,其捕鲸行为违背了《国际捕鲸管制公约》。日本表示尊重国际法院的裁决,并有所收敛了一段时间,但捕鲸活动仍未终止。2018年9月,在IWC的巴西峰会上,日本重提恢复商业捕鲸的诉求,但又一次遭到委员会的否决。这被视为日本最终退出该组织的直接原因被“科研”捕杀的鲸鱼,是如何被送上餐桌的?以科研名义被捕杀的鲸鱼,最后被输送到日本国内,满足人们的口腹之欲。负责执行这一系列动作的是一个名为日本鲸类研究所的机构,其上属机构是日本水产厅。日本鲸类研究所对鲸鱼肉有一个有趣的称呼:科研调查的副产物。他们称,根据《国际捕鲸规则公约》第8条的规定,调查后的鲸鱼体应被尽可能充分地利用。因而在鲸鱼被捕捞到渔船上并完成了对其体型、皮脂、胃内容物等款项的检测后,鲸体即会被拆解,用于鲸肉消费品的生产。当渔船抵达日本后,一块块的鲸肉会被分送给日本各级消费市场,或是以远低于市场价的价格出售给各地政府、供应于日本小学生的午餐中。";
    float[] curWidth = new float[1];
    private int mScreenHeight;
    private Bitmap mBitmap;

    public TextMultiDrawView(Context context) {
        super(context);
        init(context);
    }

    public TextMultiDrawView(Context context, AttributeSet set) {
        super(context, set);
        init(context);
    }
    private void init(Context context){
        mPaint = new Paint();
        mPaint.setTextSize(Utils.dp2px(15));
        mTextPaint = new TextPaint();
        mTextPaint.setTextSize(Utils.dp2px(15));
        mScreenHeight = Utils.getScreenHeight(context);
        mBitmap = Utils.getBitmapByWidth(context.getResources(), R.mipmap.ic_launcher_round,Utils.dp2px(100));
    }
    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //根据提供的测量值提取模式
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //根据提供的测量值提取大小
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if(heightMode == MeasureSpec.UNSPECIFIED){//为什么这么写
            setMeasuredDimension(widthSize,mScreenHeight *2);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap,getWidth() - Utils.dp2px(100),100,mPaint);
        //其实核心方法就这个breakText()
        //index是当前可存放的字符串个数
        //参数一 :是文案
        //参数二:是为true,则从头开始进行向前测量。 *否则,请从头开始向后测量
        //参数三:要累积的最大宽度
        //参数四:可选的。如果不为null,则返回测量的实际宽度*
        int index = mPaint.breakText(text,true,getWidth(),curWidth);
        canvas.drawText(text,0,index,0,100,mPaint);
        int oldIndex = index;
        index = mPaint.breakText(text,index,text.length(),true,getWidth() - Utils.dp2px(100),curWidth);
        canvas.drawText(text,oldIndex,oldIndex + index,0,100 + mPaint.getFontSpacing(),mPaint);
        oldIndex = index;
        index = mPaint.breakText(text,index,text.length(),true,getWidth() - Utils.dp2px(100),curWidth);
        canvas.drawText(text,oldIndex,oldIndex + index,0,100 + mPaint.getFontSpacing()*2,mPaint);
    }
}

2.圆形头像绘制

public class RoundView extends View {
    /**
     * 画笔
     */
    private Paint mPaint;
    /**
     * 原型图
     */
    private Bitmap src;

    public RoundView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 初始化画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        // 拿到原型图
        src = BitmapFactory.decodeResource(getResources(), R.drawable.timg);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        // 设置画布的颜色为透明
        canvas.drawColor(Color.RED);

        // 这个方法相当于PS新建图层,下面你要做的事就在这个图层上操作
        //https://www.yimipuzi.com/1139.html
        canvas.saveLayer(0, 0, getMeasuredWidth(), getMeasuredHeight(), null, Canvas.ALL_SAVE_FLAG);
        // 划出你要显示的圆
        canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, getMeasuredHeight() / 2,
                mPaint);
        // 设置混合模式
        // PorterDuff.Mode属性值参考 https://www.cnblogs.com/r-decade/p/6250450.html?utm_source=itdadao&utm_medium=referral
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        // 再绘制src源图
        canvas.drawBitmap(src, 0, 0, mPaint);
        // 还原混合模式
        mPaint.setXfermode(null);
        // 还原画布,相当于Ps的合并图层
        canvas.restore();
    }
}