您的位置:首页 > 移动开发 > Android开发

《Android群英传》读书笔记(5)第六章:Android绘图机制与处理技巧之一

2015-12-16 21:24 453 查看

1.屏幕参数

屏幕分辨率与DPI的对照表

密度ldpimdpihdpixhdpixxhdpi
密度值120160240320480
分辨率240x320320x480480x800720x12801080x1920
2. 在密度为160的屏幕上,即分辨率为320x480的屏幕上,1dp = 1px;在其他屏幕则可以通过比例进行计算,在mdpi中1dp = 1px,hdpi中1dp = 1.5px,xhdpi中1dp = 2px,在xxhdpi中1dp = 3px。

3. 单位换算

下面代码是px、dp、sp相互转换的工具类,可以集成到工程中来使用。

public class DisplayUtil{
public static int px2dp(Context context,float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}

public static int dp2px(Context context,float dpValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dpValue * scale + 0.5f);
}

public static int px2sp(Context context,float pxValue){
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int)(pxValue / fontScale + 0.5f);
}

public static int sp2px(Context context,float spValue){
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int)(spValue * fontScale + 0.5f);
}
}


或者使用Android提供的
TypedVaule
中的方法来实现:

protected int dp2px(int dp){
return (int)TypedVaule.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,getResources().getDisplayMetrics());
}

protected int sp2px(int sp){
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,sp,getResources().getDisplayMetrics());
}


2.2D绘图基础

Paint类中提供的一些方法:

setAntiAlias();//设置画笔抗锯齿效果
setColor();//设置画笔的颜色
setARGB();//设置画笔的A、R、G、B的值
setAlpha();//设置画笔的Alpha值
setTextSize();//设置字体的大小
setStyle();//设置画笔的风格(空心或者实心Paint.Style.STROKE或Paint.Style.FILL)
setStrokeWidth();//设置画笔空心边框宽度


Canvas类的一些方法

canvas.drawPoint(x,y,paint);//画点
canvas.drawLine(startX,startY,endX,endY,paint);//画线
canvas.drawLines(float[] pts,Paint paint);//画多条线
canvas.drawRect(left,top,right,bottom,paint);//画矩形
canvas.drawRoundRect(left,top,right,bottom,radiusX,radiusY,paint);//画圆角矩形
canvas.drawCircle(circleX,circleY,radius,paint);//画圆
//画弧、扇形
canvas.drawArc(left,top,right,bottom,startAngle,sweepAngle,useCenter,paint);//startAngle:起始角度,sweepAngle:扫过的角度,useCenter:boolean类型,为true时画出来的是扇形,false画出来的是弧线
canvas.drawText(text,startX,startY,paint);//画文本
canvas.drawPosText(text,
new float[]{X1,Y1,
X2,Y2,
.....
Xn,Yn},
paint);//在指定位置绘制文本
canvas.drawOval(left,top,right,bottom,paint);//画椭圆
Path path = new Path();
path.moveTo(50,50);
path.lineTo(100,100);
path.lineTo(100,300);
path.lineTo(300,50);
canvas.drawPath(path,paint);//绘制路径


3.Android中的XML绘图

1.Bitmap

在XML中使用Bitmap非常简单:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"/>


通过这样引用一张图片,就可以将图片直接转成了Bitmap在程序中使用。

2.shape

通过shape可以在XML中绘制任何形状,下面展示了Shape所支持的参数

<shape
xmlns:android="http://schemas.android.com/apk/res/android"
//默认为rectangle
android:shape=["rectangle"|"oval"|"line"|"ring"]>
<corners //当shape="rectangle"时使用
//半径,会被后面的单个半径属性覆盖
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLegtRadius="integer"
android:bottomRightRadius="integer"/>
<gradient   //渐变
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="color"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear"|"radial"|"sweep"]
android:useCenter=["true"|"false"]/>
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer"/>
<size //指定大小,一般用在ImageView配合scaleType属性使用
android:width="integer"
android:height="integer"/>
<solid  //填充颜色
android:color="color"/>
<stroke //指定边框
android:width="integer"
android:color="color"
//虚线宽度
android:dashWidth="integer"
//虚线间隔宽度
android:dashGap="integer"/>
</shape>


3.Layer

Layer是在PhotoShop中非常常用的功能,在Android中,同样可以通过Layer来实现类似的概念

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--图片一-->
<item
android:drawable="@drawable/ic_launcher"/>
<!--图片二-->
<item
android:drawable="@drawable/ic_launcher"
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"/>
</layer-list>


layer-list
中的图片会依次叠加

4.selector

Selector的作用在于帮助开发者实现静态绘图中的事件反馈,通过给不同的设置不同的图像,从而在程序中根据用户输入,返回不同的效果。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
<!-- 默认时的背景图片 -->
<item android:drawable="@drawable/X1"/>
<!-- 没有焦点时的背景图片 -->
<item android:state_window_focused="false"
android:drawable="@drawable/X2"/>
<!-- 非触摸模式下获得焦点并单击时的背景图片 -->
<item android:state_window_focused="true"
android:state_pressed="true"
android:drawable="@drawable/X3"/>
<!-- 触摸模式下单击时的背景图片 -->
<item android:state_window_focused="false"
android:state_pressed="true"
android:drawable="@drawable/X4"/>
<!-- 选中时的图片背景 -->
<item android:state_selected="true"
android:drawable="@drawable/X5"/>
<!-- 获得焦点时的图片背景 -->
<item android:state_focused="true"
android:drawable="@drawable/X6"/>
</selector>


Selector还可以和shape共同作用

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#33444444"/>
<corners android:radius="5dp"/>
<padding android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
<corners android:radius="5dp"/>
<padding android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"/>
</shape>
</item>
</selector>


4.Android绘图技巧

1.Canvas

Canvas中的几个方法:

Canvas.save();//
Canvas.restore();
Canvas.translate();
Canvas.rotate();


Canvas.save()意为保存画布,它的作用就是将之前所有已绘制的图像保存起来,让后续的操作像是在一个新的图层上操作。

Canvas.restore()可以理解为合并图层的操作,是将save()之前绘制的图像和之后绘制的图像进行合并。

Canvas.translate()和Canvas.rotate()分别为平移画布和旋转画布,更像是对坐标系的平移和旋转,例如调用translate(x,y)会将原点(0,0)移动到(x,y),之后的所有操作都将以(x,y)为原点执行。

一般在对Canvas调用translate或者rotate之前需要调用save()方法,然后translate或rotate方法之后的内容绘制完成后再调用restore()方法。

先来看一下Android绘图的坐标系,坐标零点位于屏幕左上角,向下为Y轴正方向,向右为X轴正方向。

2.Layer图层

Android中通过调用
saveLayer()
saveLayerAlpha()
方法将一个图层入栈,使用
restore()
restoreToCount()
方法将一个图层出栈。入栈的时候后面所有的操作都将发生在这个图层上,而出栈的时候,则会把图像绘制到上层Canvas上。下面的代码展示了如何使用Layer:

@Override
protected void onDraw(Canvas canvas){
canvas.drawColor(Color.WHITE);
mPaint.setColor(Color.BLUE);
canvas.drawCircle(150,150,100,mPaint);
canvas.saveLayerAlpha(0,0,400,400,127,LAYER_FLAGS);
mPaint.setColor(Color.RED);
canvas.drawCircle(200,200,100,mPaint);
canvas.restore();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: