Android群英传读书笔记第六章(Android绘图机制与处理技巧)

本文主要是介绍Android群英传读书笔记第六章(Android绘图机制与处理技巧),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

笔记

尺寸单位转换

   public static int dp2px(int dp, Context context) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,context.getResources().getDisplayMetrics());}public static int dip2px(int dip,Context context){float scale = context.getResources().getDisplayMetrics().density;return (int) (dip*scale+0.5f);}public static int sp2px(int sp,Context context){float scale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (sp*scale+0.5f);}

Android绘图
先看下Canvas的操作

  • save():将所有之前绘制的图像保存起来,让后续的操作好像在一个新的图层一样
  • restore():将save之后绘制的图像和save之前的图像合并。
  • translate()和rotate():画布平移旋转,也可以理解过坐标的平移旋转,这样更加好理解。

    接下来我们绘制一个表盘。
    这里写图片描述

public class ClockView extends View {Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);Paint degreePaint = new Paint(Paint.ANTI_ALIAS_FLAG);Paint hourPaint = new Paint(Paint.ANTI_ALIAS_FLAG);Paint minutePaint = new Paint(Paint.ANTI_ALIAS_FLAG);private int height;private int width;public ClockView(Context context, AttributeSet attrs) {super(context, attrs);init();}public void init(){circlePaint.setStyle(Paint.Style.STROKE);circlePaint.setStrokeWidth(5);circlePaint.setColor(Color.RED);hourPaint.setStrokeWidth(10);minutePaint.setStrokeWidth(8);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);height = getMeasuredHeight();width = getMeasuredWidth();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawCircle(width/2,height/2,width/2,circlePaint);drawDegree(canvas);drawHourAndMinute(canvas);}private void drawHourAndMinute(Canvas canvas) {canvas.save();canvas.translate(width/2,height/2);canvas.drawLine(0,0,100,100,hourPaint);canvas.drawLine(0,0,200,100,minutePaint);canvas.drawRect(0,0,20,20,hourPaint);canvas.restore();}public void drawDegree(Canvas canvas){for (int i = 0; i < 24; i++) {if(i==0||i==6||i==12||i==18){degreePaint.setStrokeWidth(5);degreePaint.setTextSize(30);canvas.drawLine(width/2,height/2-width/2,width/2,height/2 - width/2+60,degreePaint);String degree = String.valueOf(i);canvas.drawText(degree,width/2-degreePaint.measureText(degree)/2,height/2-width/2+90,degreePaint);}else{degreePaint.setStrokeWidth(3);degreePaint.setTextSize(20);canvas.drawLine(width/2,height/2-width/2,width/2,height/2 - width/2+30,degreePaint);String degree = String.valueOf(i);canvas.drawText(degree,width/2-degreePaint.measureText(degree)/2,height/2-width/2+60,degreePaint);}canvas.rotate(15,width/2,height/2);}}
}

Layer图层
通过saveLayer()来创建一个图层,基于栈的结构进行管理。
相关方法:
saveLayer();
saveLayerAlpha()
restore:()
restoreToCount()

色彩特效处理
这里写图片描述

变换颜色值的两种方法

  • 改变偏移量
  • 改变颜色系数

    颜色效果处理

  • 色调:matrix.setRotate();

  • 饱和度:matrix.setSaturation();
  • 亮度:matrix.setScale();

Android系统不允许修改原图,要先创建一个原图的副本,然后利用这个副本创建一个画布,最后把原图绘制到画布中。

  Bitmap bmp = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bmp);Paint paint  = new Paint();canvas.drawBitmap(bm,0,0,paint);

通过ColorMatrix的set方法,可以将一个一维数组转化为ColorMatrix
这里写图片描述

Android图形处理
Android的图形变换是一个3X3的矩阵,图形变化的初始矩阵也是对角线全部为1的矩阵

图形变化包含下面四个基本操作

  • 平移
  • 旋转
  • 缩放
  • 错切

Shader
- BitmapShader
- LinearGradient
- RadiaGradient
- SweepGradient
- ComposeShader

填充模式

  • CLAMP:拉伸,拉伸的是图片的最后一个像素,不断重复
  • REPEAT:重复:横向,纵向不断重复
  • MIRROR:镜像:横向不断重复旋转,纵向不断重复旋转

    SurfaceView
    Android系统通过发出VSYNC信号来进行屏幕的重绘,刷新的时间间隔为16ms.

SurfaceView和View的区别
- View主要适用于主动更新情况,而SurfaceView主要适用于被动更新,例如频繁的刷新
- View在主线程中对画面刷新,而SurfaceView会通过一个子线程来刷新
- SurfaceView在底层实现了双缓冲机制
- 当程序需要更新View上的图像时,程序必须重绘View上显示的整张图片

如果你的自定义View需要频繁刷新,或者刷新时数据量比较大,就可以使用SurfaceView了。下面来看两个SurfaceView的例子

绘制正弦曲线

这里写图片描述

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {private SurfaceHolder surfaceHolder;private Canvas canvas;private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//控制子线程private boolean mIsDrawing;private int x = 0;private int y;private Path mPath = new Path();public MySurfaceView(Context context, AttributeSet attrs) {super(context, attrs);surfaceHolder = getHolder();surfaceHolder.addCallback(this);setFocusable(true);setFocusableInTouchMode(true);setKeepScreenOn(true);paint.setColor(Color.RED);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(5);}/*** surfaceview创建* @param holder*/@Overridepublic void surfaceCreated(SurfaceHolder holder) {mIsDrawing = true;new Thread(this).start();}/*** surfaceview改变* @param holder* @param format* @param width* @param height*/@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}/*** surfaceview销毁* @param holder*/@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {mIsDrawing = false;}@Overridepublic void run() {while(mIsDrawing){draw();x+=1;y = (int) (100*Math.sin(x*2*Math.PI/180)+400);mPath.lineTo(x,y);}}public void draw(){try {canvas = surfaceHolder.lockCanvas();//设置画布背景颜色canvas.drawColor(Color.WHITE);canvas.drawPath(mPath,paint);}catch (Exception e){}finally {//对画布内容进行提交,放在finally里面可以保证执行if(canvas!=null){surfaceHolder.unlockCanvasAndPost(canvas);}}}
}

画布

这里写图片描述

public class SurfaceViewCanvas extends SurfaceView implements SurfaceHolder.Callback,Runnable {private SurfaceHolder mHolder;private Canvas canvas;private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);private boolean mIsDrawing;private Path mPath = new Path();public SurfaceViewCanvas(Context context, AttributeSet attrs) {super(context, attrs);mHolder = getHolder();mHolder.addCallback(this);setFocusable(true);setFocusableInTouchMode(true);setKeepScreenOn(true);paint.setColor(Color.RED);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(10);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {mIsDrawing = true;}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {new Thread(this).start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {mIsDrawing =false;}@Overridepublic void run() {long start = System.currentTimeMillis();while(mIsDrawing){draw();}long end = System.currentTimeMillis();if(end - start <100){try {Thread.sleep(100-(end - start));} catch (InterruptedException e) {e.printStackTrace();}}}private void draw(){try {canvas = mHolder.lockCanvas();canvas.drawColor(Color.WHITE);canvas.drawPath(mPath,paint);}catch (Exception e){}finally {if(canvas!=null){mHolder.unlockCanvasAndPost(canvas);}}}@Overridepublic boolean onTouchEvent(MotionEvent event) {int x = (int) event.getX();int y = (int) event.getY();switch (event.getAction()){case MotionEvent.ACTION_DOWN:mPath.moveTo(x,y);break;case MotionEvent.ACTION_MOVE:mPath.lineTo(x,y);break;case MotionEvent.ACTION_UP:break;}return true;}
}

与上一个例子不同的地方在于,我们对绘制的频率进行了限制,因为我们有时候不需要很频繁的绘制,这里的100mx是一个大致的经验证,这个值的范围一般在50ms到100mx之间。

这篇关于Android群英传读书笔记第六章(Android绘图机制与处理技巧)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/592450

相关文章

Python调用LibreOffice处理自动化文档的完整指南

《Python调用LibreOffice处理自动化文档的完整指南》在数字化转型的浪潮中,文档处理自动化已成为提升效率的关键,LibreOffice作为开源办公软件的佼佼者,其命令行功能结合Python... 目录引言一、环境搭建:三步构建自动化基石1. 安装LibreOffice与python2. 验证安装

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束