Canvas
sdk root folder]\samples\ApiDemos\src\com\android\samples\graphics
Java代码:
-
// 使用红色,并让它50%透明
-
int opacity = 127;
-
int intColor = Color.argb(opacity, 255, 0, 0);
-
int parsedColor = Color.parseColor("#7FFF0000");
Java代码:
-
// 让颜色50%透明
-
int opacity = 127;
-
myPaint.setAlpha(opacity);
提示:
定义渐变Shader
java代码:
-
int colorFrom = Color.BLACK;
-
int colorTo = Color.WHITE;
-
LinearGradient linearGradientShader = new LinearGradient(x1, y1, x2, y2, colorFrom, colorTo, TileMode.CLAMP);
java代码:
-
int[] gradientColors = new int[3];
-
gradientColors[0] = Color.GREEN;
-
gradientColors[1] = Color.YELLOW;
-
gradientColors[2] = Color.RED;
-
float[] gradientPositions = new float[3];
-
gradientPositions[0] = 0.0f;
-
gradientPositions[1] = 0.5f;
-
gradientPositions[2] = 1.0f;
-
RadialGradient radialGradientShader=new RadialGradient(centerX,centerY, radius, gradientColors, gradientPositions, TileMode.CLAMP);
使用Shader TileModes
使用MaskFilter
java代码:
-
// 设置光源的方向
-
float[] direction = new float[]{ 1, 1, 1 };
-
//设置环境光亮度
-
float light = 0.4f;
-
// 选择要应用的反射等级
-
float specular = 6;
-
// 向mask应用一定级别的模糊
-
float blur = 3.5f;
-
EmbossMaskFilter emboss=new EmbossMaskFilter(direction,light,specular,blur);
-
// 应用mask myPaint.setMaskFilter(emboss);
使用ColorFilter
Android包含三个ColorFilter:
PathEffect对于绘制Path基本图形特别有用,但是它们也可以应用到任何Paint中从而影响线条绘制的方式。
DashPathEffect
java代码:
-
borderPaint.setPathEffect(new CornerPathEffect(5));
修改Xfermode
java代码:
-
AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); borderPen.setXfermode(avoid);
3. 使用抗锯齿效果提高Paint质量
java代码:
-
myPaint.setSubpixelText(true);
-
myPaint.setAntiAlias(true);
2D图形的硬件加速
java代码:
-
myActivity.requestWindowFeature(Window.FEATURE_OPENGL);
Canvas绘图最佳实践经验
高级指南针表盘的例子
java代码:
-
<?xml version="1.0" encoding="utf-8"?>
-
<resources>
-
<color name="text_color">#FFFF</color>
-
<color name="background_color">#F000</color>
-
<color name="marker_color">#FFFF</color>
-
<color name="shadow_color">#7AAA</color>
-
<color name="outer_border">#FF444444</color>
-
<color name="inner_border_one">#FF323232</color>
-
<color name="inner_border_two">#FF414141</color>
-
<color name="inner_border">#FFFFFFFF</color>
-
<color name="horizon_sky_from">#FFA52A2A</color>
-
<color name="horizon_sky_to">#FFFFC125</color>
-
<color name="horizon_ground_from">#FF5F9EA0</color>
-
<color name="horizon_ground_to">#FF00008B</color>
-
</resources>
-
(2) 用作航空地平仪的天空和地面的Paint和Shader对象是根据当前View的大小创建的,所以它们不能像你在创建的Paint对象那样,是静态的。因此,不再创建Paint对象,取而代之的是构造它们所使用的渐变数组和颜色。
java代码:
-
int[] borderGradientColors;
-
float[] borderGradientPositions;
-
int[] glassGradientColors;
-
float[] glassGradientPositions;
-
int skyHorizonColorFrom;
-
int skyHorizonColorTo;
-
int groundHorizonColorFrom;
-
int groundHorizonColorTo;
(3) 更新CompassView的initCompassView方法,来使用第(1)步中所创建的资源来初始化第(2)步中所创建的变量。现存的方法代码大部分可以保留,而只需要对textPaint、circlePaint和markerPaint变量做些许改动,如下所示:
java代码:
-
protected void initCompassView() {
-
setFocusable(true);
-
// 获得外部资源
-
Resources r = this.getResources();
-
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
circlePaint.setColor(R.color.background_color);
-
circlePaint.setStrokeWidth(1);
-
circlePaint.setStyle(Paint.Style.STROKE);
-
northString = r.getString(R.string.cardinal_north);
-
eastString = r.getString(R.string.cardinal_east);
-
southString = r.getString(R.string.cardinal_south);
-
westString = r.getString(R.string.cardinal_west);
-
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
textPaint.setColor(r.getColor(R.color.text_color));
-
textPaint.setFakeBoldText(true);
-
textPaint.setSubpixelText(true);
-
textPaint.setTextAlign(Align.LEFT);
-
textHeight = (int)textPaint.measureText("yY");
-
markerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
markerPaint.setColor(r.getColor(R.color.marker_color));
-
markerPaint.setAlpha(200);
-
markerPaint.setStrokeWidth(1);
-
markerPaint.setStyle(Paint.Style.STROKE);
-
markerPaint.setShadowLayer(2, 1, 1, r.getColor(R.color.shadow_color));
java代码:
-
borderGradientColors = new int[4];
-
borderGradientPositions = new float[4];
-
borderGradientColors[3] = r.getColor(R.color.outer_border);
-
borderGradientColors[2] = r.getColor(R.color.inner_border_one);
-
borderGradientColors[1] = r.getColor(R.color.inner_border_two);
-
borderGradientColors[0] = r.getColor(R.color.inner_border);
-
borderGradientPositions[3] = 0.0f;
-
borderGradientPositions[2] = 1-0.03f;
-
borderGradientPositions[1] = 1-0.06f;
java代码:
-
glassGradientColors = new int[5];
-
glassGradientPositions = new float[5];
-
int glassColor = 245;
-
glassGradientColors[4]=Color.argb(65,glassColor,glassColor, glassColor);
-
glassGradientColors[3]=Color.argb(100,glassColor,glassColor,glassColor);
-
glassGradientColors[2]=Color.argb(50,glassColor,glassColor, glassColor);
-
glassGradientColors[1]=Color.argb(0,glassColor,glassColor, glassColor);
-
glassGradientColors[0]=Color.argb(0,glassColor,glassColor, glassColor);
-
glassGradientPositions[4] = 1-0.0f;
-
glassGradientPositions[3] = 1-0.06f;
-
glassGradientPositions[2] = 1-0.10f;
-
glassGradientPositions[1] = 1-0.20f;
-
glassGradientPositions[0] = 1-1.0f;
java代码:
- skyHorizonColorFrom = r.getColor(R.color.horizon_sky_from);
- skyHorizonColorTo = r.getColor(R.color.horizon_sky_to);
- groundHorizonColorFrom = r.getColor(R.color.horizon_ground_from);
- groundHorizonColorTo = r.getColor(R.color.horizon_ground_to);
java代码:
-
Path skyPath = new Path();
-
skyPath.addArc(innerBoundingBox, -tiltDegree, (180 + (2 * tiltDegree)));
java代码:
-
canvas.rotate(-rollDegree, px, py);
-
canvas.drawOval(innerBoundingBox, groundPaint);
-
canvas.drawPath(skyPath, skyPaint);
-
canvas.drawPath(skyPath, markerPaint);
java代码:
-
int markWidth = radius / 3; int startX = center.x - markWidth; int endX = center.x + markWidth;
java代码:
-
double h = innerRadius*Math.cos(Math.toRadians(90-tiltDegree)); double justTiltY = center.y - h;
java代码:
-
float pxPerDegree = (innerBoundingBox.height()/2)/45f;
java代码:
-
for (int i = 90; i >= -90; i -= 10) {
-
double ypos = justTiltY + i*pxPerDegree;
-
// 只显示内表盘的刻度
-
if ((ypos < (innerBoundingBox.top + textHeight)) || (ypos > innerBoundingBox.bottom - textHeight)) continue;
-
// 为每一个刻度增加画一个直线和一个倾斜角
-
canvas.drawLine(startX, (float)ypos, endX, (float)ypos, markerPaint);
-
t displayPos = (int)(tiltDegree - i);
-
String displayString = String.valueOf(displayPos);
-
float stringSizeWidth = textPaint.measureText(displayString);
-
canvas.drawText(displayString, (int)(center.x-stringSizeWidth/2), (int)(ypos)+1, textPaint);
-
}
java代码:
-
markerPaint.setStrokeWidth(2);
-
canvas.drawLine(center.x - radius / 2, (float)justTiltY, center.x + radius / 2, (float)justTiltY, markerPaint);
-
markerPaint.setStrokeWidth(1);
java代码:
-
// 绘制箭头
-
Path rollArrow = new Path();
-
rollArrow.moveTo(center.x - 3, (int)innerBoundingBox.top + 14);
-
rollArrow.lineTo(center.x, (int)innerBoundingBox.top + 10);
-
rollArrow.moveTo(center.x + 3, innerBoundingBox.top + 14);
-
rollArrow.lineTo(center.x, innerBoundingBox.top + 10);
-
canvas.drawPath(rollArrow, markerPaint);
-
// 绘制字符串
-
String rollText = String.valueOf(rollDegree);
-
double rollTextWidth = textPaint.measureText(rollText);
-
canvas.drawText(rollText, (float)(center.x - rollTextWidth / 2), innerBoundingBox.top + textHeight + 2, textPaint);
java代码:
-
canvas.restore();
java代码:
-
canvas.save();
-
canvas.rotate(180, center.x, center.y);
-
for (int i = -180; i < 180; i += 10) {
-
// 每30度显示一个数字值
-
if (i % 30 == 0) {
-
String rollString = String.valueOf(i*-1);
-
float rollStringWidth = textPaint.measureText(rollString);
-
PointF rollStringCenter = new PointF(center.x-rollStringWidth / 2, innerBoundingBox.top+1+textHeight);
-
canvas.drawText(rollString, rollStringCenter.x, rollStringCenter.y, textPaint);
-
}
-
// 否则,绘制一个标记直线
-
else { canvas.drawLine(center.x, (int)innerBoundingBox.top, center.x, (int)innerBoundingBox.top + 5, markerPaint);
-
}
-
canvas.rotate(10, center.x, center.y);
-
}
-
canvas.restore();