>>继承自View
>>使用Canvas绘图
每次View组件上的图形状态数据发生了改变,都应该通知View组件重写调用onDraw(Canvas canvas)方法重绘该组件。通知View重绘可调用invalidate(在UI线程中)或postInvalidate(在非UI线程中)。
采用双缓冲实现绘图板。表现上看起来是随用户在触摸屏上自由地画曲线,实际上依然利用的是Canvas的drawLine方法画直线。借助于Android提供的Path类,可以非常方便地实现这种效果。
需要指出的是,如果程序每次都只是从上次拖动事件的发生点绘一条直线到本次拖动事件的发生点,那么用户前面绘制的就会丢失。为了保留用户之前绘制的内容,程序要借助于“双缓冲”技术。
所谓双缓冲技术其实很简单:当程序需要在指定View上进行绘制时,程序并不直接绘制到该View组件上,而是先绘制到一个内存中的Bitmap图片(这就是缓冲)上,等到内存中的Bitmap绘制好之后,再一次性地将Bitmap绘制到View组件上。
该程序需要一个自定义View,该View的代码如下。
public class DrawView extends View { float preX; float preY; private Path path; //记住所有的Path,允许返回1步 private Path paths[] = new Path[1]; public Paint paint = null; final int VIEW_WIDTH = 320; final int VIEW_HEIGHT = 480; //定义一个内存中的图片,该图片将作为缓冲区 Bitmap cacheBitmap = null; //定义cacheBitmap上的Canvas对象 Canvas cacheCanvas = null; public DrawView(Context context, AttributeSet set) { super(context, set); //创建一个与该View相同大小的缓存区 cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT, Config.ARGB_8888); cacheCanvas = new Canvas(); path = new Path(); //设置cacheCanvas将会绘制到内存中的cacheBitmap上 cacheCanvas.setBitmap(cacheBitmap); //设置画笔的颜色 paint = new Paint(Paint.DITHER_FLAG); paint.setColor(Color.RED); //设置画笔风格 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); //反锯齿 paint.setAntiAlias(true); paint.setDither(true); } @Override public boolean onTouchEvent(MotionEvent event) { //获取拖动事件的发生位置 float x = event.getX(); float y = event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: path.moveTo(x, y); preX = x; preY = y; break; case MotionEvent.ACTION_MOVE: path.quadTo(preX, preY, x, y); preX = x; preY = y; break; case MotionEvent.ACTION_UP: cacheCanvas.drawPath(path, paint); paths[0] = path; path.reset(); break; } invalidate(); //返回true表明处理方法已经处理该事件 return true; } @Override public void onDraw(Canvas canvas) { Paint bmpPaint = new Paint(); //将cacheBitmap绘制到该View组件上 canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); //沿着path绘制 canvas.drawPath(path, paint); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)