自定义View-第五步:绘制图片

前言

根据Gcssloop所学习的自定义View整理与笔记。

准备

** 禁用GPU硬件加速**

  1. 在AndroidManifest.xml文件为application标签添加如下的属性即可为整个应用程序开启/关闭硬件加速:

  1. 在Activity 标签下使用 hardwareAccelerated 属性开启或关闭硬件加速:
  
  1. 在Window 层级使用如下代码开启硬件加速:(Window层级不支持关闭硬件加速)
getWindow().setFlags(  
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,  
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); 
  1. View 级别如下关闭硬件加速:(view 层级上不支持开启硬件加速)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);

或者使用android:layerType=”software”来关闭硬件加速

  

一、drawPicture:录制Canvas中绘制的内容

** 使用Picture前请关闭硬件加速,以免引起不必要的问题!**
详情请进入这里->Android的硬件加速及可能导致的问题

首先,了解一下Picture的方法吧~

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

现在开始使用啦♪(*)

  1. 第一步:使用Picture录制内容
//录制内容
private void recording() {
    Canvas canvas = picture.beginRecording(500, 500);
    canvas.translate(250, 250);
    canvas.drawCircle(0, 0, 100, paint);
    picture.endRecording();
}
  • 第二步:将录制的内容显示出来(三种方式)
    1. 使用Picture提供的draw方法绘制。
// 将Picture中的内容绘制在Canvas上,一般不使用 
       picture.draw(canvas);

效果图为:


自定义View-第五步:绘制图片_第1张图片
  1. 使用Canvas提供的drawPicture方法绘制,会缩放。
public void drawPicture (Picture picture)
public void drawPicture (Picture picture, Rect dst)
public void drawPicture (Picture picture, RectF dst)

举个栗子:

        paint.setColor(Color.RED);
        canvas.drawRect(0, 0, 100, 200, paint);
        paint.setColor(Color.BLACK);
        canvas.drawPicture(picture, new RectF(0, 0, 100, 200));

效果图为:


自定义View-第五步:绘制图片_第2张图片
**绘制的内容根据选区进行了缩放**
  1. 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制,不会缩放。
  paint.setColor(Color.RED);
  canvas.drawRect(0, 0, 250, picture.getHeight(), paint);
 paint.setColor(Color.BLACK);
 // 包装成为Drawable
 PictureDrawable drawable = new PictureDrawable(picture);
// 设置绘制区域 -- 注意此处所绘制的实际内容不会缩放
drawable.setBounds(0, 0, 250, picture.getHeight());
// 绘制
drawable.draw(canvas);

效果图:


自定义View-第五步:绘制图片_第3张图片
此处setBounds是设置在画布上的绘制区域,并非根据该区域进行缩放,也不是剪裁Picture,每次都从Picture的左上角开始绘制

ps:三种方法的主要区别:
是否对Canvas有影响: 1有影响;2,3不影响
此处指绘制完成后是否会影响Canvas的状态(Matrix clip等)
可操作性强弱: 1可操作性较弱;2,3可操作性较强
此处的可操作性可以简单理解为对绘制结果可控程度。

接下来上代码喽

二、drawBitmap

看到bitmap有点怕怕的,哈哈,内存泄漏的大麻烦啊,GcsSloop简单的讲解了一下,那我也跟着简单的学一下讲一下吧,嘿嘿
1.第一步:通过BitmapFactory从不同位置获取Bitmap

//资源文件(drawable/mipmap/raw)中获取
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap);
//资源文件(assets)
Bitmap bitmap=null;
try {
 InputStream is = mContext.getAssets().open("bitmap.png");
 bitmap = BitmapFactory.decodeStream(is);
 is.close();
} catch (IOException e) {
 e.printStackTrace();
}
//内存卡文件
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");
//网络文件
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

2.第二步:绘制Bitmap

  1. 第一种
/** * Draw the bitmap using the specified matrix. * 
* @param bitmap The bitmap to draw
 * @param matrix The matrix used to transform the bitmap when it is drawn
 * @param paint  May be null. The paint used to draw the bitmap
 */
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
    nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),            
paint != null ? paint.getNativeInstance() : 0);
}

demo:

canvas.drawBitmap(bitmap,new Matrix(),new Paint());

2.第二种

 /** 
* @param bitmap The bitmap to be drawn
 * @param left   The position of the left side of the bitmap being drawn 
* @param top    The position of the top side of the bitmap being drawn 
* @param paint  The paint used to draw the bitmap (may be null) 
*/
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
    throwIfCannotDraw(bitmap);
    native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top, 
           paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
}

**left、top:此处指定的是与坐标原点的距离,并非是与屏幕顶部和左侧的距离, 虽然默认状态下两者是重合的,但是也请注意分别两者的不同。
**

demo:

canvas.drawBitmap(bitmap,200,200,new Paint());

3.第三种

 /* 
@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);

demo:

// 将画布坐标系移动到画布中央
canvas.translate(200, 200);
// 指定图片绘制区域(左上角的四分之一)
Rect src = new Rect(0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
// 指定图片在屏幕上显示的区域
Rect dst = new Rect(0, 0, 100, 200);
// 绘制图片
canvas.drawBitmap(bitmap, src, dst, null);
自定义View-第五步:绘制图片_第4张图片
效果

你可能感兴趣的:(自定义View-第五步:绘制图片)