




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Android群英传笔记第五章:Android Scroll分析(1)一.屏幕的尺寸信息屏幕的尺寸,主要还是因为Android的屏幕确实五花八门,所以在一定程度上的适配问题也是很捉急的,所以我们要对这块屏幕充分的认识1.屏幕参数一块屏幕通常具备以下的几个参数屏幕大小指屏幕对角线的长度,通常用寸来表示,例如4.7寸,5.5寸分辨率分辨率是指实际屏幕的像素点个数,例如720X1280就是指屏幕的分辨率,宽有720个像素点,高有1280个像素点PPI每英寸像素又称为DPI,他是由对角线的的像素点数除以屏幕的大小所得,通常有400PPI就已经很6了2.系统屏幕密度每个厂商的安卓手机具有不同的大小尺寸和
2、像素密度的屏幕,安卓系统如果要精确到每种DPI的屏幕,基本上是不可能的,因此系统定义了几个标准的DPI3.独立像素密度dp这是由于各种屏幕密度的不同,导致同样像素大小的长度,在不同密度的屏幕上显示长度不同,因此相同长度的屏幕,高密度的屏幕包含更多的像素点,在安卓系统中使用mdpi密度值为160的屏幕作为标准,在这个屏幕上,1px = 1dp,其他屏幕则可以通过比例进行换算,例如同样是100的长度,mdpi中为100px,而在hdpi中为150,我们也可以得出在各个密度值中的换算公式,在mdpi中 1dp = 1px, 在hdpi中, 1dp = 1.5px,在xhdpi中,1dp = 2px,
3、在xxhdpi中1dp = 3px,由此可见,我们换算公司 l:m:h:xh:xxh = 3:4:6:8:124.单位换算在程序中,我们可以非常方便地对一些单位的换算,下面的代码给出了一种换算的方法我们可以把这些代码作为工具类保存在项目中package com.lgl.playview;import android.content.Context;/* * dp,sp转换成px的工具类 * Created by lgl on 16/3/23. */public class DisplayUtils /* * 将px值转换成dpi或者dp值,保持尺寸不变 * * param content *
4、param pxValus * return */ public static int px2dip(Context content, float pxValus) final float scale = content.getResources().getDisplayMetrics().density; return (int) (pxValus / scale + 0.5f); /* * 将dip和dp转化成px,保证尺寸大小不变。 * * param content * param pxValus * return */ public static int dip2px(Context
5、 content, float pxValus) final float scale = content.getResources().getDisplayMetrics().density; return (int) (pxValus / scale + 0.5f); /* * 将px转化成sp,保证文字大小不变。 * * param content * param pxValus * return */ public static int px2sp(Context content, float pxValus) final float fontScale = content.getRes
6、ources().getDisplayMetrics().scaledDensity; return (int) (pxValus / fontScale + 0.5f); /* * 将sp转化成px,保证文字大小不变。 * * param content * param pxValus * return */ public static int sp2px(Context content, float pxValus) final float fontScale = content.getResources().getDisplayMetrics().scaledDensity; retur
7、n (int) (pxValus / fontScale + 0.5f); 其实的density就是前面所说的换算比例,这里使用的是公式换算方法进行转换,同时系统也提供了TypedValue帮助我们转换 /* * dp2px * param dp * return */ protected int dp2px(int dp) return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,getResources().getDisplayMetrics(); /* * sp2px * param dp * return
8、*/ protected int sp2px(int sp) return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,sp,getResources().getDisplayMetrics(); 二.2D绘图基础系统通过提供的Canvas对象来提供绘图方法,它提供了各种绘制图像的API,drawLine,deawPoint,drawRect,drawVertices,drawAce,drawCircle等等,我以前写过Android绘图机制(二)自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的
9、坐标讲解,通过他们的名字我们基本可以大致了解他们的功能,当然,Paint作为一个非常重要的元素功能也非常强大这里也简单地列举了一些他的属性Android绘图机制(一)自定义View的基础属性和方法 setAntiAlias(); /设置画笔的锯齿效果setColor(); /设置画笔的颜色setARGB(); /设置画笔的A、R、G、B值setAlpha(); /设置画笔的Alpha值setTextSize(); /设置字体的尺寸setStyle(); /设置画笔的风格(空心或实心)setStrokeWidth(); /设置空心边框的宽度getColor(); /获取画笔的颜色是由于画笔功能的
10、不一样,再结合各种不同的绘图API,这样任意组合就可以实现不同的绘图效果,比如同样是矩形设置Paint就Style可以画出空心或者实心,我们来看看RectViewpackage com.lgl.playview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;/* * Created b
11、y lgl on 16/3/23. */public class RectView extends View private Paint paint1,paint2; public RectView(Context context, AttributeSet attrs) super(context, attrs); initView(); private void initView() paint1 = new Paint(); paint1.setColor(Color.BLUE); paint1.setAntiAlias(true); /空心 paint1.setStyle(Paint.
12、Style.STROKE); paint2 = new Paint(); paint2.setColor(Color.BLUE); /实心 paint2.setStyle(Paint.Style.FILL); Override protected void onDraw(Canvas canvas) super.onDraw(canvas); canvas.drawRect(50,100,300,300,paint1); canvas.drawRect(350,400,700,700,paint2); 运行起来就是三.Android XML 绘图XML在安卓系统中可不仅仅是Java中的一个布局
13、文件配置列表,在安卓开发者的手头上他甚至可以变成一张画,一幅画,Android开发者给XML提供了几个强大的属性1.Bitmap在XML中使用Bitmap很简单通过这样引用图片就可以将图片直接转化成Bitmap让我们在程序中使用2.Shape通过Shape可以绘制各种图形,下面展示一下shape的参数 android:dashWidth= 1dp android:dashGap= 1dpshape可以说是xml绘图的精华所在,而且功能十分的强大,无论是扁平化,拟物化还是渐变,都是十分的OK,我们现在来做一个阴影的效果 看效果3.LayerLayer是在PhotoShop中是非常常用的功能,在A
14、ndroid中,我们同样可以实现图层的效果 4.SelectorSelector的作用是帮助开发者实现静态View的反馈,通过设置不同的属性呈现不同的效果 这一方法可以帮助开发者迅速制作View的反馈,通过配置不同的触发事件,selector会自动选中不同的图片,特别是自定义button的时候,而我们不再使用原生单调的背景,而是使用selector特别制作的背景,就能完美实现触摸反馈了通常情况下,上面提到的这些方法都可以共同实现,下面这个例子就展示了在一个selector中使用shape作为他的item的例子,实现一个具体点击反馈效果的,圆角矩形的selector,代码如下 我们来看一下效果图
15、四.Android绘图技巧在学完Android的基本绘图之后我们来讲解一下常用的绘图技巧1.CanvasCanvas作为绘制图形的直接对象,提供了一下几个非常有用的方法Canvas.save()Canvas.restore()Canvas.translate()Canvas.roate()首先,我们来看一下前面两个方法在讲解这两个方法之前,首先来了解一下Android绘图的坐标体系,这个其实这个前面已经讲了,这里不赘述,而Canvas.save()这个方法,从字面上的意思可以理解为保存画布,他的作用就是讲之前的图像保存起来,让后续的操作能像在新的画布一样操作,这跟PS的图层基本差不多而Canv
16、as.restore()这个方法,则可以理解为合并图层,就是讲之前保存下来的东西合并而后面两个方法尼?从字母上理解画布平移或者旋转,但是把他理解为坐标旋转更加形象,前面说了,我们绘制的时候默认坐标点事左上角的起始点,那么我们调用translate(x,y)之后,则将原点(0,0)移动到(x,y)之后的所有绘图都是在这一点上执行的,这里可能说的不够详细,最典型的例子是画一个表盘了,那我们这里就演示一下画一个表盘我们先来分析一下这个表盘有什么?我们可以将他分解1.仪表盘外面的大圆盘2.刻度线包含四个长的刻度线和其他短的刻度线3.刻度值包含长刻度线对应的大的刻度尺和其他小的刻度尺4.指针中间的指针,
17、一粗一细两根相信如果现实中叫你去画一个仪表盘的话,你应该也会这样的步骤去画,实际上Android上的绘图远比现实中的绘制十分的相似,与PS的绘图更家相似,当然,我们在绘制一个复杂的图形之后,不妨先把思路请清除了这个示例中,我们第一步,先画表盘,现在画个圆应该很轻松了。关键在于确定圆心和半径,这里直接居中吧/ 画外圆Paint paintCircle = new Paint();paintCircle.setAntiAlias(true);paintCircle.setStyle(Paint.Style.STROKE);paintCircle.setStrokeWidth(5);canvas.d
18、rawCircle(mWidth / 2, mHeight / 2, mWidth / 2, paintCircle);下面,我们来画刻度尺,这个也很简单,一条线而已,只要确定两个端点的位置就可以,第一根线还是比较容易确定的,那后面的我们怎么去确定尼?那些斜着的我们可以用三角函数去实现计算,但是这其实就是一个很简单的画图,三角函数的运算也要这么多,我们不经要思考,该怎么去简化他尼?其实Google已经为我们想好了我们治国与会觉得这个不好画,主要是这个角度,那么如果我们将画布以中心为原点旋转到需要的角度尼?每当画好一根线,我们就旋转多少级角度,但是下一次划线的时候依然是第一次的坐标,但是实际上我
19、们把画布重新还原到旋转钱的坐标了,所有的刻度线就已经画好了,通过旋转画布实际上是旋转了画图的坐标轴,这就避免了万恶的三角函数了,通过这样一种相对论式的变换,间接简化了绘图,这时再去绘制这些刻度,是不是要简单了,只需要区别整点和非整点的刻度了 / 画刻度 Paint paintDegree = new Paint(); paintDegree.setStrokeWidth(3); for (int i = 0; i 24; i+) / 区别整点和非整点 if (i = 0 | i = 6 | i = 12 | i = 18) paintDegree.setStrokeWidth(5); pain
20、tDegree.setTextSize(30); canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth, mHeight / 2 - mWidth / 2 + 60, paintDegree); String degree = String.valueOf(i); canvas.drawText(degree, mWidth / 2 - paintDegree.measureText(degree) / 2, mHeight / 2 - mWidth / 2 + 90, paintDegree); else paintDegr
21、ee.setStrokeWidth(3); paintDegree.setTextSize(15); canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth, mHeight / 2 - mWidth / 2 + 30, paintDegree); String degree = String.val ueOf(i); canvas.drawText(degree, mWidth / 2 - paintDegree.measureText(degree) / 2, mHeight / 2 -
22、mWidth / 2 + 60, paintDegree); / 通过旋转画布简化坐标运算 canvas.rotate(15, mWidth / 2, mHeight / 2); 我们看看效果紧接着,我们就可以来绘制两根针了,我们可以这样来绘制 / 画指针 Paint paintHour = new Paint(); paintHour.setStrokeWidth(20); Paint paintMinute = new Paint(); paintMinute.setStrokeWidth(10); canvas.save(); canvas.translate(
23、mWidth / 2, mHeight / 2); canvas.drawLine(0, 0, 100, 100, paintHour); canvas.drawLine(0, 0, 100, 200, paintMinute); canvas.restore();这样运行的效果就和最上面的效果图一样了,这里贴上完整的代码package com.lgl.dial;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.Attri
24、buteSet;import android.view.View;import android.view.WindowManager;public class DialView extends View / 宽高 private int mWidth; private int mHeight; / 构造方法 public DialView(Context context, AttributeSet attrs) super(context, attrs); / 获取屏幕的宽高 WindowManager wm = (WindowManager) getContext().getSystemSe
25、rvice( Context.WINDOW_SERVICE); mWidth = wm.getDefaultDisplay().getWidth(); mHeight = wm.getDefaultDisplay().getHeight(); Override protected void onDraw(Canvas canvas) / TODO Auto-generated method stub super.onDraw(canvas); / 画外圆 Paint paintCircle = new Paint(); paintCircle.setAntiAlias(true); paint
26、Circle.setStyle(Paint.Style.STROKE); paintCircle.setStrokeWidth(5); canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, paintCircle); / 画刻度 Paint paintDegree = new Paint(); paintDegree.setStrokeWidth(3); for (int i = 0; i 24; i+) / 区别整点和非整点 if (i = 0 | i = 6 | i = 12 | i = 18) paintDegree.setStro
27、keWidth(5); paintDegree.setTextSize(30); canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 60, paintDegree); String degree = String.valueOf(i); canvas.drawText(degree, mWidth / 2 - paintDegree.measureText(degree) / 2, mHeight / 2 - mWidth / 2 + 90, paintDeg
28、ree); else paintDegree.setStrokeWidth(3); paintDegree.setTextSize(15); canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 30, paintDegree); String degree = String.valueOf(i); canvas.drawText(degree, mWidth / 2 - paintDegree.measureText(degree) / 2, mHeight /
29、 2 - mWidth / 2 + 60, paintDegree); / 通过旋转画布简化坐标运算 canvas.rotate(15, mWidth / 2, mHeight / 2); / 画指针 Paint paintHour = new Paint(); paintHour.setStrokeWidth(20); Paint paintMinute = new Paint(); paintMinute.setStrokeWidth(10); canvas.save(); canvas.translate(mWidth / 2, mHeight / 2); canvas.drawLine
30、(0, 0, 100, 100, paintHour); canvas.drawLine(0, 0, 100, 200, paintMinute); canvas.restore(); 2.Layer图层Android中的绘图API,很大程度上都来自绘图的API,特别是借鉴了很多PS的原理,比如图层的概念,相信看过图层的也都知道是个什么样的,我们画个图来分析一下Android通过saveLayer()方法,saveLayerAlpha()将一个图层入栈,使用restore()方法,restoreToCount()方法将一个图层出栈,入栈的时候,后面的所有才做都是发生在这个图层上的,而出栈的时候
31、,则会把图层绘制在上层Canvas上,我们仿照API Demo来Override protected void onDraw(Canvas canvas) / TODO Auto-generated method stub super.onDraw(canvas); canvas.drawColor(Color.WHITE); mPaint.setColor(Color.BLUE); canvas.drawCircle(150, 150, 100, mPaint); canvas.saveLayerAlpha(0, 0,400,400,127,LAYER_TYPE_NONE); mPaint.
32、setColor(Color.RED); canvas.drawCircle(200, 200, 100, mPaint); canvas.restore(); 当绘制两个相交的圆时,就是图层 接下来将图层后面的透明度设置成0-255不同值 我们分别演示 127 255 0三个五.Android图像处理之色彩特效处理Android对于图片的处理,最常用的数据结构是位图Bitmap,他包含了一张图片的所有数据,整个图片都是由点阵和颜色值去组成的,所谓的点阵就是一个包含像素的矩形,每一个元素对应的图片就是一个像素,而颜色值ARGB,分别对应透明度红,绿,蓝,这四个通用的分量,他们共同决定了每个像素
33、点显示的颜色1.色彩矩阵分析在色彩处理中,我们通常用三个角度描述一张图片色调物体传播的颜色饱和度颜色的纯度,从0-100来进行描述亮度颜色的相对,明暗程度而在Android中,系统会使用一个颜色矩阵ColorMatrix,来处理这些色彩的效果,Android中的颜色矩阵是4X5的数字矩阵,他用来对颜色色彩进行处理,而对于每一个像素点,都有一个颜色分量矩阵来保存ARGB值这些是这样归类的第一行的abcde用来决定新的颜色值R红色第二行的fghij用来决定新的颜色值G绿色第三行的kimno用来决定新的颜色值B蓝色第四行的pqrst用来决定新的颜色值A透明这样划分好各自的范围之后,这些值就比较慢明确
34、了,不过只这样说可能会比较抽象,我们通过几个小李子不断的去分析首先,我们来看一下矩阵变换的计算公式,以R分量为例,计算过程是R1 = a * R + b* G + c*B+d *A + e如果让a = 1,b,c,d,e都等于0,那么计算的结果为R1 = R,因此我们可以构建一个矩阵如果把这个矩阵公式带入R1 = AC,那么根据矩阵的乘法运算法则,可以得到R1 = R;因此,这个矩阵通常是用来作为初始的颜色矩阵来使用,他不会对原有颜色进行任何改变那么当我们要变换颜色值的时候通常有两种方法,一个是直接改变颜色的offset,即修改颜色的分量。另一种方法直接改变RGBA值的系数来改变颜色分量的值。
35、-1.改变偏移量从前面的分析中,可以知道要修改R1的值,只要将第五列的值进行修改即可,即改变颜色的偏移量,其它值保存初始矩阵的值,如图所示的颜色矩阵实现了这样的效果。在上面这个矩阵中,我们修改了R,G,所对应的颜色偏移量,那么最后的处理结果,就是图像的红色绿色分别增加了100,而我们知道,红色混合绿色的到了黄色,所以最终的颜色处理结果就是让整个图片的色调偏黄色-2.改变颜色系数如果修改颜色分量中的某个系数值而其他只依然保存初始矩阵的值。在上面这个矩阵中改变了G分量所对应的系数据g,这样在矩形运算后G分量会变成以前的两倍,最终效果就是图像的色调更加偏绿。-3.改变色光属性图像的色调,饱和度,亮度这三个属性在图像处理中使用的非常多,因此在颜色矩阵中也封装了一些API来快速调用这些参数,而不用每次都去计算矩阵的值。下面通过一个实例来看看如何通过句正改变图像的色调,饱和度和亮度。在Android中,系统封装了一个类ColorMatrix,也就是前面所说的颜色矩阵。通过这个类,可以很方便地通过改变矩阵值来处理颜色的效果,创建一个ColorMatrix对象非常简单代码如下。ColorMatrix colorMatrix = ne
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 运输物流公司管理制度
- 饲料公司安全管理制度
- 软件行业薪酬管理制度
- 西药处方审核管理制度
- 进修医师宿舍管理制度
- 防护器具佩戴管理制度
- 企业消防室管理制度
- 运营助理店铺管理制度
- 超市信息安全管理制度
- 装修公司管理制度资料
- 第9课《桃花源记》教学设计-2024-2025学年统编版语文八年级下册
- 2025年绍兴职业技术学院单招职业适应性测试题库附答案
- 网络系统维护记录日志表
- 广东省广州市白云区2024-2025学年高三下学期2月统测英语试卷【含答案解析】
- 2023-2024学年广东省广州市天河区八校联考七年级(下)期中数学试卷(含答案)
- deepseek的使用技巧与实际应用培训课件
- 禁食病人护理措施
- 存款保险知识竞赛
- 信息技术必修1数据与计算2.2《做出判断的分支》教学设计
- 七年级生物上册 3.2.1 种子的萌发说课稿1 (新版)新人教版
- 2025年春季中小学升旗仪式安排表(附:1-20周讲话稿)
评论
0/150
提交评论