前言
根据Gcssloop所学习的自定义View整理与笔记。
准备
** 禁用GPU硬件加速**
- 在AndroidManifest.xml文件为application标签添加如下的属性即可为整个应用程序开启/关闭硬件加速:
- 在Activity 标签下使用 hardwareAccelerated 属性开启或关闭硬件加速:
- 在Window 层级使用如下代码开启硬件加速:(Window层级不支持关闭硬件加速)
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
- 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中
现在开始使用啦♪(∇*)
- 第一步:使用Picture录制内容
//录制内容
private void recording() {
Canvas canvas = picture.beginRecording(500, 500);
canvas.translate(250, 250);
canvas.drawCircle(0, 0, 100, paint);
picture.endRecording();
}
- 第二步:将录制的内容显示出来(三种方式)
- 使用Picture提供的draw方法绘制。
// 将Picture中的内容绘制在Canvas上,一般不使用
picture.draw(canvas);
效果图为:
- 使用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));
效果图为:
- 将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);
效果图:
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
- 第一种
/** * 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);