自定义view-drawBitmap巧妙使用
来源:互联网 发布:it分销 编辑:程序博客网 时间:2024/06/05 19:35
参考文档:
1.http://www.gcssloop.com/customview/Canvas_PictureText 作者:GcsSloop
本篇文章讲的是,canvas绘制bitmap中的drawBitmap函数的一个比较有意思的使用方法,我们以后也许会用到也说不定的哦。
我们先来浏览一下这个函数:
publicvoiddrawBitmap(Bitmapbitmap,Rectsrc,Rectdst,Paintpaint)
publicvoiddrawBitmap(Bitmapbitmap,Rectsrc,RectFdst,Paintpaint)
其中src和dst这两个矩形区域是用来做什么的?
Rect src:指定绘制图片的区域
Rect dst或RectF dst:指定图片在屏幕上的绘制(显示)区域
来看一个示例:
// 将画布坐标系移动到画布中央canvas.translate(mWidth/2,mHeight/2);// 指定图片绘制区域(左上角的四分之一)Rect src = new Rect(0,0,bitmap.getWidth()/2,bitmap.getHeight()/2);// 指定图片在屏幕上显示的区域Rect dst = new Rect(0,0,200,400);// 绘制图片canvas.drawBitmap(bitmap,src,dst,null);
详解:
上面是以绘制该图为例,用src选择图片的绘制区域,即下图红色区域。
用dst指定图片绘制(显示)在屏幕上面的区域,也就是图片的实际显示区域,用户可以看到的,即下图中蓝色方框标注的区域,图片宽高会根据这个指定区域自动进行缩放。
从上面可知,第三种方法可以绘制图片的一部分到画布上,这有什么用呢?
如果你看过某些游戏的资源文件,你可能会看到如下的图片(图片来自网络):
用一张图片包含了大量的素材,在绘制的时候每次只截取一部分进行绘制,这样可以大大的减少素材数量,而且素材管理起来也很方便。
然而这和我们有什么关系呢?我们又不做游戏开发。
确实,我们不做游戏开发,但是在某些时候我们需要制作一些炫酷的效果,这些效果因为太复杂了用代码很难实现或者渲染效率不高。这时候很多人就会想起帧动画,
将动画分解成一张一张的图片然后使用帧动画制作出来,这种实现方式的确比较简单,但是一个动画效果的图片有十几到几十张,一个应用里面来几个这样炫酷的动画效果
就会导致资源文件出现一大堆,想找其中的某一张资源图片简直就是灾难啊有木有。但是把同一个动画效果的所有资源图片整理到一张图片上,会大大的减少资源文件数量,
方便管理,妈妈再也不怕我找不到资源文件了,同时也节省了图片文件头、文件结束块以及调色板等占用的空间。
下面是利用drawBitmap第三种方法制作的一个简单示例:资源文件如下:
最终效果如下:
其实实现起来非常简单,跟上面示例的代码大致相同,只不过自定义了一个动画效果,可以看看代码:
package com.rick.customview.view.checkview;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.os.Handler;import android.os.Message;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.util.Log;import android.view.View;import com.rick.customview.R;/** * 利用drawBitmap第三种方法制作的一个简单示例 * <p> * Created by MyPC on 2017/5/16. */public class CheckView extends View { private static final int ANIM_NULL = 0; //动画状态-没有 private static final int ANIM_CHECK = 1; //动画状态-开启 private static final int ANIM_UNCHECK = 2; //动画状态-结束 private Context mContext; // 上下文 private int mWidth, mHeight; // 宽高 private Handler mHandler; // handler private Paint mPaint; private Bitmap mBitmap; private int animCurrentPage = -1; // 当前页码 private int animMaxPage = 13; // 总页数 private int animDuration = 500; // 动画时长 private int animState = ANIM_NULL; // 动画状态 private boolean isCheck = false; // 是否只选中状态 public CheckView(Context context) { this(context, null); } public CheckView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); } //初始化 private void init(Context context) { mContext = context; mPaint = new Paint(); mPaint.setColor(0xffFF5317); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.checkmark); mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (animCurrentPage < animMaxPage && animCurrentPage >= 0) { if (animState == ANIM_NULL) { return; } if (animState == ANIM_CHECK) { animCurrentPage++; } else if (animState == ANIM_UNCHECK) { animCurrentPage--; } invalidate(); this.sendEmptyMessageDelayed(0, animDuration / animMaxPage); Log.e("AAA", "current=" + animCurrentPage); } else { if (isCheck) { animCurrentPage = animMaxPage - 1; } else { animCurrentPage = -1; } invalidate(); animState = ANIM_NULL; } } }; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 移动坐标系到画布中央 canvas.translate(mWidth / 2, mHeight / 2); // 绘制背景圆形 canvas.drawCircle(0, 0, 240, mPaint); // 得出图像边长 int sideLength = mBitmap.getHeight(); // 得到图像选区 和 实际绘制位置 Rect src = new Rect(sideLength * animCurrentPage, 0, sideLength * (animCurrentPage + 1), sideLength); Rect dst = new Rect(-200, -200, 200, 200); // 绘制 canvas.drawBitmap(mBitmap, src, dst, null); } /** * 选择 */ public void check() { if (animState != ANIM_NULL || isCheck) { return; } animState = ANIM_CHECK; animCurrentPage = 0; mHandler.sendEmptyMessageDelayed(0, animDuration / animMaxPage); isCheck = true; } /** * 取消选择 */ public void unCheck() { if (animState != ANIM_NULL || !isCheck) { return; } animState = ANIM_UNCHECK; animCurrentPage = animMaxPage - 1; mHandler.sendEmptyMessageDelayed(0, animDuration / animMaxPage); isCheck = false; } /** * 设置动画时长 * * @param animDuration */ public void setAnimDuration(int animDuration) { if (animDuration <= 0) return; this.animDuration = animDuration; } /** * 设置背景圆形颜色 * * @param color */ public void setBackgroundColor(int color) { mPaint.setColor(color); }}OK,drawBitmap的使用,在这里就结束了。
- 自定义view-drawBitmap巧妙使用
- Android 自定义View canvas.drawBitmap使用举例
- android.view.GLES20RecordingCanvas.drawBitmap异常
- 使用drawBitmap绘制图片
- DrawBitmap
- 【自定义控件】练习:drawBitmap显示长图
- 自定义imageview中的canvas.drawBitmap方法
- 自定义View的使用
- 自定义view的使用
- android 自定义View使用
- 使用xib自定义 view
- 自定义View详细使用
- android中Canvas使用drawBitmap绘制图片
- android中Canvas使用drawBitmap绘制图片
- android中Canvas使用drawBitmap绘制图片
- Android 中Canvas.drawBitmap()的使用
- android中Canvas使用drawBitmap绘制图片
- android 中Canvas使用drawBitmap画图
- TabLayout + ViewPager,点击tab,导致闪屏问题
- Executors类中创建线程池的几种方法的分析
- thinkPHP数据库--存储过程待续
- 【备忘】李炎恢Bootstrap视频教程下载
- oracle数据库_实例_用户_表空间之间的关系
- 自定义view-drawBitmap巧妙使用
- do{...}while(0)的意义
- cacti 搭建与使用
- 下载软件版本后概率性出现某些单体必现无声
- Java多态例子
- 关于ORACLE 在windos 环境下出现ORA-12546的问题研究
- Win32串口操作的技巧
- 安装 360的 poseidon
- javascript的原生dom知识点