自定义view绘图篇--图片和文字的绘制

图片的绘制功能可以让我们直接添加一张图片到画布,文字的绘制可以点缀我们view的功能。本章节继续深入,总结下其中的流程。

知识点

在这里插入图片描述

一、绘制图片

1、Picture类

(1)Picture类的功能

我们可以把Picture看作是录制Canvas操作的录像机。

(2)使用步骤

1、录制(使用Picture的一些方法开始录制)
2、显示(吧录制的内容绘制出来)

(3)Pictire的常用方法

  • public int getWidth ()
    获取宽度
  • public int getHeight ()
    获取高度
  • public Canvas beginRecording (int width, int height)
    开始录制 (返回一个Canvas,在Canvas中所有的绘制都会存储在Picture中)
    参数width、height:画布宽高
  • public void endRecording ()
    结束录制
  • public void draw (Canvas canvas)
    将Picture中内容绘制到Canvas中

(4)录制栗子

public class BasicView extends View {

    private Paint paint;
    private Picture picture;
    private Canvas recoredCanvas;


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

    public BasicView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BasicView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        picture = new Picture();//Picture 对象

        paint = new Paint();// 初始化画笔
        paint.setColor(Color.BLUE);
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(8);
        paint.setStyle(Paint.Style.STROKE);

        // 录制操作
        recoredCanvas = picture.beginRecording(500,500); // 开始录制  返回一个新的画布对象
        recoredCanvas.translate(300, 300);//更改新的画布中心点
        recoredCanvas.drawRect(-300, -300, 300, 300, paint); //新的画布上画 矩形
        picture.endRecording();// 结束录制
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

虽然把我们在canvas上作图的操作记录了一遍,但是我们不去主动的调用是看不到的。(比如我们手机录了一段视屏,录制完成后我们需要点击播放才能观看)

(5)显示

显示我们录制的方式有三种(选择任一)

^ _ ^ Picture 类的draw方法

上文Picture类中有介绍

^ _ ^ Canvas类的drawPicture方法

public void drawPicture (Picture picture)

public void drawPicture (Picture picture, Rect dst) //dst 更改画布Picture中的画布宽高(有缩放的效果)

public void drawPicture (Picture picture, RectF dst)//dst 更改画布Picture中的画布宽高(有缩放的效果)

ps:更改画布Picture中的画布宽高,不影响当前画布。(显示在当前画布上时,会缩放)

^ _ ^ PictureDrawable的draw方法

方法参数和Picture的draw一致

^ _ ^ 上述三个方法使用栗子


  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //吧录制的画布绘制出来

        //  picture.draw(canvas); // 1、picture 的drawable方法
        //   canvas.drawPicture(picture); //2 Canvas 的drawPicture方法


        // 3、PictureDrawable 的draw方法
        PictureDrawable drawable = new PictureDrawable(picture); 
        drawable.setBounds(0,0,200,200); // 从画布的左上角开始按照矩形区域绘制(显示左上角开始矩形区域内的团)
        drawable.draw(canvas);

    }

注意:
1、对象获得的方式
2、Canvas的drawPicture的后两个方法使用(会缩放)
3、PictureDrawable 的setBounds效果不是缩放,而是指定绘制的区域。

2、drawBitmap

Canvas提供啦drawBitmap方法,可以方便的让我们把一张位图直接绘制到canvas上。

(1)Bitmap相关

其实bitmap的相关知识还是不少的,比如引发oom、图片缩放、等。如果不了解可以看看以下文章。

1、Bitmap的加载和Cache
2、Android性能优化

(2)常用方法

    // 方法1
    public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)
    
    // 方法2
    public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)
    
    // 方法3
    public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
    public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

方法1、看参数很简单,就是第二个参数Matrix ,我们使用默认的直接new对象就行啦
方法2、(left,op)指定bitmap的左上角的点。其实也可以理解为指定bitmap左边、上边距离坐标xy轴距离。
方法3、 Rect src指定图片绘制区域。Rect dst 指定图片在屏幕上显示(绘制)的区域

(3)方法3的参数详解

src :原图片中截取一个矩形图片(矩形尺寸和原图片一样大时代表完整截取原图片)
dst:吧截取的图片显示在des矩阵中(大小自适应des矩阵)

源码

  /*
   * @param bitmap The bitmap to be drawn
     * @param src May be null. The subset of the bitmap to be drawn
     * @param dst The rectangle that the bitmap will be scaled/translated to fit into(自适应可能就会缩放或者拉伸)
     * @param paint May be null. The paint used to draw the bitmap
     */
    public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
            @Nullable Paint paint) {
        super.drawBitmap(bitmap, src, dst, paint);
    }

参考:Canvas之drawBitmap方法

(4)使用drawBitmap方法3 实现逐帧动画效果

我们都知道,view播放逐帧动画时,事前你要先准备一些动画素材,这些图片多时就避免不了内存增大。其实使用drawBitmap 使用一张完整的图片即可完成逐帧的效果。

可以参考大佬的栗子:
传送门

二、绘制文字

1、paint字体相关常用方法
1、setColor setARGB 设置颜色
2、setAlpha 透明度
3、setTextSize 设置文字大小
4、setTypeface 设置字体样式
5、setStyle 设置填充效果
6、setTextAlign设置对齐方式(左对齐(LEFT),居中对齐(CENTER),右对齐(RIGHT)7、paint.setFakeBoldText(true);//设置是否为粗体文字
8、paint.setUnderlineText(true);//设置下划线
9、paint.setStrikeThruText(true);//设置带有删除线效果

10、paint.setTextSkewX((float) -0.25);//设置字体水平倾斜度,普通斜体字是-0.25,可见往右斜
2、绘制文字方法分类
    // 第一类:指定位置绘制文字
    public void drawText (String text, float x, float y, Paint paint)//指定位置绘制 
    public void drawText (String text, int start, int end, float x, float y, Paint paint)
    public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
    public void drawText (char[] text, int index, int count, float x, float y, Paint paint)
    
    // 第二类 :分别指定每个文字的位置
    public void drawPosText (String text, float[] pos, Paint paint)
    public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
    
    // 第三类:随之path绘制
    public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
    public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

1、第一类中的start 、end 理解:可以理解为字符串中字符的截取。截取[start,end)索引字符绘制
2、第二类中的pos数组理解:字符位置数组,内的每一个点代表每一个字符的位置。(不建议使用)

坑:
必须指定所有字符位置否则蹦
大量使用的时候可能导致卡顿
不支持emoji等特殊字符,不支持字形组合与分解

3、随着path路径绘制文字

float hOffset : 与路径起始点的水平偏移距离
float vOffset : 与路径中心的垂直偏移量
ps:也就是从指定偏移位置开始绘制

3、字体样式Typeface

paint 的setTypeface (Typeface typeface)就是用来设置字体风格的

(1)常见Typeface对象的创建

 // 1、使用系统字体
 Typeface	create(String familyName, int style) //加载系统字体
 // 2、自定义字体(例如:加载ttf文件)
 Typeface	createFromAsset(AssetManager mgr, String path) //通过从Asset中获取外部字体来显示字体样式
 Typeface	createFromFile(String path)//直接从路径创建
 Typeface	createFromFile(File path)//从外部路径来创建字体样式
 //3、简单创建个Typeface对象
 Typeface	defaultFromStyle(int style)//创建默认字体

(2)style的枚举值

Typeface.NORMAL  //正常体
Typeface.BOLD	//粗体
Typeface.ITALIC	//斜体
Typeface.BOLD_ITALIC //粗斜体

end

下一篇:自定义view绘图篇–贝塞尔曲线
参考文章:
Canvas之图片文字
自定义控件之绘图篇(二):路径及文字

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值