編輯:關於Android編程
Canvas() //構造方法 Canvas(Bitmap bitmap) //帶參構造方法,創建一個以bitmap位圖為背景的Canvas
clipPath(Path path, Region.Op op) //根據特殊path組合裁切圖像,Region.Op定義了Region支持的區域間運算種類。 clipRect(Rect rect, Region.Op op) //根據矩形組合裁切圖像 clipRegion(Region region, Region.Op op) concat(Matrix matrix) //通過matrix的設置可以對繪制的圖形進行繪制伸縮和位移
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) //繪制弧形 drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) //繪制bitmap位圖 drawPicture(Picture picture, RectF dst) //繪制圖片 drawCircle(float cx, float cy, float radius, Paint paint) //繪制圓 drawLine(float startX, float startY, float stopX, float stopY, Paint paint) //繪制線 drawLines(float[] pts, int offset, int count, Paint paint) //可以選擇性的去掉一些數據繪制多條線 drawOval(RectF oval, Paint paint) //繪制橢圓 drawPath(Path path, Paint paint) //繪制路徑 drawPoint(float x, float y, Paint paint) //繪制點 drawPoints(float[] pts, int offset, int count, Paint paint) //繪制多個點 drawPosText(String text, float[] pos, Paint paint) //繪制文本,float[] pos指定每個文本位置 drawRect(float left, float top, float right, float bottom, Paint paint) //繪制矩形 drawRoundRect(RectF rect, float rx, float ry, Paint paint) //繪制圓角矩形 drawText(String text, float x, float y, Paint paint) //繪制string文本 drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) //路徑上繪制文本
drawRGB(int r, int g, int b) //使用RGB指定顏色填充canvas的bitmap畫布 drawARGB(int a, int r, int g, int b) //使用ARGB指定顏色填充canvas的bitmap畫布
save() //保存Canvas狀態,save之後,可以調用Canvas的平移、放縮、旋轉、錯切、裁剪等操作 restore() //恢復Canvas之前保存的狀態,防止save後對Canvas執行的操作對後續的繪制有影響 rotate(float degrees, float px, float py) //旋轉 scale(float sx, float sy) //縮放 skew(float sx, float sy) //扭曲 translate(float dx, float dy) //平移
isUnderlineText() //判斷是否有下劃線 setUnderlineText(boolean underlineText) //設置下劃線 getLetterSpacing() //獲取字符間的間距 setLetterSpacing(float letterSpacing) //設置字符間距 getFontSpacing() //獲取行間距 isStrikeThruText() //判斷文本是否有刪除線 setStrikeThruText(boolean strikeThruText) //設置文本刪除線 getTextSize() //獲取字體大小 setTextSize(float textSize) //設置字體大小 getTypeface() //獲取文字字體類型 setTypeface(Typeface typeface) //設置文字字體類型 getTextSkewX() //獲取斜體文字的值 setTextSkewX(float skewX) //設置斜體文字的值,負數為右傾斜,正數為左傾斜 官方推薦-0.25 getTextScaleX() //獲取文字水平縮放值 setTextScaleX(float scaleX) //設置文本水平縮放值 getTextAlign() //獲取文本對其方式 setTextAlign(Paint.Align align) //設置文本對其方式 ascent() //baseline之上至字符最高處的距離 descent() //baseline下面到字符最低處的距離 measureText(CharSequence text, int start, int end) //測繪文本的寬度 getTextBounds(char[] text, int index, int count, Rect bounds) //獲取文本寬高 getTextWidths(String text, int start, int end, float[] widths) //精確獲取文本寬度 getTextLocale() //獲取文本語言地理位置 setTextLocale(Locale locale) //設置文本地理位置,也就是設置對應的語言
//設置畫筆顏色 setARGB(int a, int r, int g, int b) setAlpha(int a) setColor(int color) //獲取畫筆顏色 getAlpha() getColor() isAntiAlias() //判斷是否抗鋸齒 setAntiAlias(boolean aa) //設置抗鋸齒,雖然耗資源耗時間,但是一般會開啟 getStyle() //獲取畫筆樣式 setStyle(Paint.Style style) //設置畫筆樣式,FILL:實心; FILL_OR_STROKE:同時實心和空心; STROKE:空心 setStrokeCap(Cap cap) //設置畫筆樣式, 圓形(Cap.Round),方形(Cap.SQUARE) getStrokeWidth() //獲取畫筆的粗細大小 setStrokeWidth(float width) //設置畫筆的粗細大小 clearShadowLayer() //清除陰影層 setShadowLayer(float radius, float dx, float dy, int shadowColor) //設置陰影 getXfermode() //獲取圖形繪制的像素融合模式 setXfermode(Xfermode xfermode) //設置圖形繪制的像素融合模式和疊加模式,就是新繪制的像素與Canvas上對應位置已有的像素按照混合規則進行顏色混合 getShader() //獲取圖形的渲染方式 setShader(Shader shader) //設置圖形的渲染方式,分別有線性渲染(LinearGradient) 環形渲染(RadialGradient) 組合渲染(ComposeShader) 掃描漸變渲染/梯度渲染(SweepGradient)
reset() //清除畫筆復位
package com.example.drawview;
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 by elimy on 2016-10-11.
*/
public class DrawCircleView extends View {
Paint paint;
public DrawCircleView(Context context) {
super(context);
}
public DrawCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
package com.example.drawview;
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 by elimy on 2016-10-11.
*/
public class DrawCircleView extends View {
Paint paint;
public DrawCircleView(Context context) {
super(context);
}
public DrawCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//初始化畫筆
paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
//設置畫筆要是,圓形/方形/其他
paint.setStrokeCap(Paint.Cap.BUTT);
//設置實心圓
paint.setStyle(Paint.Style.FILL);
//設置畫筆大小
paint.setStrokeWidth(2);
//設置陰影
paint.setShadowLayer(5,5,5, Color.BLUE);
//繪制實心圓
canvas.drawCircle(300,200,100,paint);
//設置為空心
paint.setStyle(Paint.Style.STROKE);
//設置畫筆大小
paint.setStrokeWidth(3);
//繪制
canvas.drawCircle(500,200,100,paint);
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-15.
*/
public class DrawRectView extends View {
public DrawRectView(Context context) {
super(context);
}
public DrawRectView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆的樣式
paint.setStrokeCap(Paint.Cap.ROUND);
//設置畫筆粗細大小
paint.setStrokeWidth(3);
//設置畫筆的所畫圖形的樣式
paint.setStyle(Paint.Style.FILL);
//設置畫筆的顏色
paint.setColor(Color.GREEN);
//繪制矩形 drawRect(left頂點X坐標, left頂點Y坐標, 右底部X坐標, 右底Y坐標, @NonNull Paint paint)
canvas.drawRect(200,200,400,400,paint);
//從新設置畫筆所畫圖形樣式
paint.setStyle(Paint.Style.STROKE);
//重新設置畫筆大小
paint.setStrokeWidth(5);
//繪制
RectF rect = new RectF(200,420,400,620);
canvas.drawRect(rect,paint);
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-14.
*/
public class DrawRoundRectView extends View {
public DrawRoundRectView(Context context) {
super(context);
}
public DrawRoundRectView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//聲明並初始化
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫出的圖形是實心還是空心
paint.setStyle(Paint.Style.FILL);
//設置畫筆粗細
paint.setStrokeWidth(2);
//設置畫筆的樣式
paint.setStrokeCap(Paint.Cap.ROUND);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorPrimaryDark));
/* if (Build.VERSION.SDK_INT>=21){
//需要在API 21版本及其以後才能使用,和下面效果相同
canvas.drawRoundRect(100,100,200,200,20,20,paint);
}*/
RectF rect = new RectF(200,200,400,400);
canvas.drawRoundRect(rect,50,50,paint);
//從新設置畫筆大小
paint.setStrokeWidth(5);
//設置畫筆畫出的圖形未空心
paint.setStyle(Paint.Style.STROKE);
//繪制矩形
// RectF(left頂點x坐標, left頂點Y坐標, right邊底部x坐標, right邊底部Y坐標)
RectF rect2 = new RectF(200,420,400,620);
//繪制圓角矩形
//drawRoundRect(@NonNull RectF rect, x方向上的圓角半徑, Y方向上的圓角半徑, @NonNull Paint paint)
canvas.drawRoundRect(rect2,50,50,paint);
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawOvalView extends View {
public DrawOvalView(Context context) {
super(context);
}
public DrawOvalView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆筆尖樣式
paint.setStrokeCap(Paint.Cap.ROUND);
//設置所畫圖形的填充樣式
paint.setStyle(Paint.Style.FILL);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
//實例化一個包裹橢圓的矩形,如果為正方形,則橢圓為圓
RectF rectF = new RectF(200,200,500,400);
//設置畫布顏色,方便與paint.setColor()對比,看看他們的區別
canvas.drawColor(Color.BLACK);
//繪制橢圓
canvas.drawOval(rectF,paint);
//設置畫筆的大小
paint.setStrokeWidth(5);
//設置繪畫圖形為空心
paint.setStyle(Paint.Style.STROKE);
//繪制
if (Build.VERSION.SDK_INT>=21){
//API 21以上才能用,與上面的繪畫方式效果一致
canvas.drawOval(200,450,500,650,paint);
}
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawPointView extends View {
public DrawPointView(Context context) {
super(context);
}
public DrawPointView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
//設置畫筆大小,我這邊設置的大點,方便觀察
paint.setStrokeWidth(50);
//設置畫筆筆尖樣式,默認為Paint.Cap.SQUARE,待會切換一下,你就會知道它的作用了
// 網上有說在設置paint.setStrokeCap(Paint.Cap.ROUND|SQUARE);之前需要同時設置
//paint.setStrokeJoin(Paint.Join.ROUND|MITER);我測試了好像不需要也能達到切換的目的
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setColor(getResources().getColor(R.color.colorAccent));
canvas.drawPoint(200,200,paint);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawPoint(300,200,paint);
paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setColor(getResources().getColor(R.color.colorAccent));
canvas.drawPoint(400,200,paint);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawPoint(500,200,paint);
//設置畫筆樣式
paint.setStrokeCap(Paint.Cap.ROUND);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
//繪制多個點
canvas.drawPoints(new float[]{150,300,250,300,350,300,450,300,550,300},paint);
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawLineView extends View {
public DrawLineView(Context context) {
super(context);
}
public DrawLineView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆樣式
paint.setStrokeCap(Paint.Cap.ROUND);
//設置畫筆顏色
paint.setColor(Color.RED);
//設置畫筆大小
paint.setStrokeWidth(20);
//畫線段,參數分別是線段起始點的坐標和終點的坐標,和預設的畫筆
canvas.drawLine(100,200,600,200,paint);
//LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
//TileMode tile),(x0,y0) (x1,y1)源碼上說是梯度的坐標,不是很懂,我個人理解為後面設置的每一種顏色渲染的長度,坐標間隔越小,渲染的顏色長度越短
//int colors[]:指示需要渲染的顏色數組 float positions[]:可為null,為null時顏色均勻分布
//TileMode tile:指示平鋪模式,分別有REPEAT(重復) CLAMP(像素擴散) MIRROR(鏡面投影)
Shader mShader=new LinearGradient(0,0,100,100,
new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},
null,Shader.TileMode.REPEAT);
//設置畫筆渲染漸變
paint.setShader(mShader);
//繪制漸變線段
canvas.drawLine(100,300,600,300,paint);
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawPathView extends View {
public DrawPathView(Context context) {
super(context);
}
public DrawPathView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆筆尖樣式
paint.setStrokeCap(Paint.Cap.ROUND);
//設置填充模式,默認為FILL
paint.setStyle(Paint.Style.FILL);
//設置畫筆大小
paint.setStrokeWidth(3);
//設置顏色
paint.setColor(getResources().getColor(R.color.colorPrimary));
/*Path類的幾個...To()方法:
* path.moveTo(x,y)移動到某個點
* path.lineTo(x,y)從起始點,默認(0,0)點繪制直線到(x,y)點
* path.arcTo()用來繪制弧形
* path.cubicTo()用來繪制貝塞爾曲線
* path.quadTo()也是繪制貝塞爾曲線的
* */
//實例化路徑類
Path path = new Path();
//設置移動,不繪制
path.moveTo(200, 200);
//從(200,200)畫到(200,400)
path.lineTo(200, 400);
//從(200,400)畫到(400,400)
path.lineTo(400, 400);
//封閉曲線
path.close();
//繪制路徑
canvas.drawPath(path, paint);
//設置顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
//設置移動,不繪制
Path path1 = new Path();
path1.moveTo(200, 200);
//從(200,200)畫到(200,400)
path1.lineTo(400, 200);
//從(200,400)畫到(400,400)
path1.lineTo(400, 400);
//封閉曲線
path1.close();
//繪制
canvas.drawPath(path1, paint);
//初始化路徑
Path path2 = new Path();
//設置矩形
RectF rectF = new RectF(420, 200, 620, 500);
//取矩形包裹橢圓0°到270°的弧
path2.arcTo(rectF, 0, 270);
//封閉弧形
path2.close();
//設置填充實心
paint.setStyle(Paint.Style.FILL);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
//繪制圖形
canvas.drawPath(path2, paint);
/*
*quadTo()繪制貝塞爾曲線
*/
Path path3 = new Path();
//移動到(200,620)點
path3.moveTo(200, 620);
//繪制貝塞爾曲線
path3.quadTo(300, 420, 400, 620);
//設置空心
paint.setStyle(Paint.Style.STROKE);
//繪制曲線
canvas.drawPath(path3, paint);
/*
* cubicTo()繪制貝塞爾曲線
* */
Path path4 = new Path();
//移動到(300,100)點
path4.moveTo(300, 100);
//繪制曲線
path4.cubicTo(300, 100, 5, 300, 300, 500);
//設置不填充
paint.setStyle(Paint.Style.STROKE);
//繪制
canvas.drawPath(path4, paint);
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-16.
*/
public class DrawTextView extends View {
public DrawTextView(Context context) {
super(context);
}
public DrawTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorPrimary));
//設置畫筆大小
paint.setStrokeWidth(3);
//設置字體大小
paint.setTextSize(30);
//設置文字樣式
paint.setTypeface(Typeface.DEFAULT_BOLD);
String str = "我知道,你要說我很帥,哈啊哈哈哈哈,字不夠長!";
//全部顯示,起點在(200,100)點
canvas.drawText(str,50,100,paint);
//截取4~9的字符串顯示
canvas.drawText(str,4,10,200,200,paint);
//實例化路徑
Path path = new Path();
//設置圓形狀路徑,Direction指示文字顯示是逆時針向外還是順時針向內 Path.Direction.CW|Path.Direction.CCW
path.addCircle(400,400,110, Path.Direction.CW);
//更具路徑繪制文本
canvas.drawTextOnPath(str,path,0,0,paint);
Path path1 = new Path();
if (Build.VERSION.SDK_INT>=21){
//API 21以上
path1.addOval(300,600,500,900, Path.Direction.CCW);
}
canvas.drawTextOnPath(str,path1,0,0,paint);
}
}

package com.example.drawview;
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 by elimy on 2016-10-16.
*/
public class DrawPosTextView extends View {
public DrawPosTextView(Context context) {
super(context);
}
public DrawPosTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
//設置抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
//設置畫筆到校
paint.setStrokeWidth(5);
//設置字體顏色
paint.setTextSize(30);
canvas.drawColor(Color.BLACK);
canvas.drawPosText("你看我帥嘛?",new float[]{100,200,200,100,300,200,300,400,200,500,100,400},paint);
}
}

3.setXfermode(Xfermode xfermode)的運用
setXfermode()方法主要是設置圖形繪制的像素融合模式和疊加模式,就是新繪制的像素與Canvas上對應位置已有的像素按照混合規則進行顏色混合
package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-17.
*/
public class XfermodeView extends View {
public XfermodeView(Context context) {
super(context);
}
public XfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* 默認的Xfermode
* */
Paint paint = getPaint();
//設置繪制圓的畫筆顏色
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 200, 100, paint);
//設置繪制圓角矩形的畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上,當然最好是些兼容性好的,我這裡只是為了方便
canvas.drawRoundRect(200, 200, 300, 350, 10, 10, paint);
/*
* PorterDuff.Mode.ADD模式
* */
Paint paint1 = getPaint();
paint1.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 200, 100, paint1);
//設置像素融合模式
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
paint1.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 200, 600, 350, 10, 10, paint1);
//取消像素融合模式的設置
paint1.setXfermode(null);
/*
* PorterDuff.Mode.CLEAR模式
* */
Paint paint2 = getPaint();
paint2.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 500, 100, paint2);
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint2.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 500, 300, 650, 10, 10, paint2);
paint2.setXfermode(null);
/*
* PorterDuff.Mode.DARKEN模式
* */
Paint paint3 = getPaint();
paint3.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 500, 100, paint3);
paint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
paint3.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 500, 600, 650, 10, 10, paint3);
paint3.setXfermode(null);
/*
* PorterDuff.Mode.LIGHTEN模式
* */
Paint paint4 = getPaint();
paint4.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 800, 100, paint4);
paint4.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));
paint4.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 800, 300, 950, 10, 10, paint4);
/*
* PorterDuff.Mode.MULTIPLY模式
* */
Paint paint5 = getPaint();
paint5.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 800, 100, paint5);
paint5.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
paint5.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 800, 600, 950, 10, 10, paint5);
paint5.setXfermode(null);
}
public Paint getPaint() {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(5);
return paint;
}
}

package com.example.drawview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by elimy on 2016-10-17.
*/
public class XfermodeView extends View {
public XfermodeView(Context context) {
super(context);
}
public XfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* 默認的Xfermode
* */
Paint paint = getPaint();
//設置繪制圓的畫筆顏色
paint.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 200, 100, paint);
//設置繪制圓角矩形的畫筆顏色
paint.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上,當然最好是些兼容性好的,我這裡只是為了方便
canvas.drawRoundRect(200, 200, 300, 350, 10, 10, paint);
/*
* PorterDuff.Mode.ADD模式
* */
//canvas.saveLayer()在canvas原畫布上見一個透明的layer
int layerId = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint1 = getPaint();
paint1.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 200, 100, paint1);
//設置像素融合模式
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
paint1.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 200, 600, 350, 10, 10, paint1);
//取消像素融合模式的設置
paint1.setXfermode(null);
//將新圖層畫到canvas上
canvas.restoreToCount(layerId);
/*
* PorterDuff.Mode.CLEAR模式
* */
int layerId2 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint2 = getPaint();
paint2.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 500, 100, paint2);
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint2.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 500, 300, 650, 10, 10, paint2);
paint2.setXfermode(null);
canvas.restoreToCount(layerId2);
/*
* PorterDuff.Mode.DARKEN模式
* */
int layerId3 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint3 = getPaint();
paint3.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 500, 100, paint3);
//禁用掉CPU硬件加速,采用軟件渲染模式,因為DARKEN、LIGHTEN、OVERLAY等幾種混合規則在GPU硬件加速效果展示不出來
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
paint3.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 500, 600, 650, 10, 10, paint3);
paint3.setXfermode(null);
canvas.restoreToCount(layerId3);
/*
* PorterDuff.Mode.LIGHTEN模式
* */
int layerId4 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint4 = getPaint();
paint4.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(200, 800, 100, paint4);
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
paint4.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));
paint4.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(200, 800, 300, 950, 10, 10, paint4);
paint4.setXfermode(null);
canvas.restoreToCount(layerId4);
/*
* PorterDuff.Mode.MULTIPLY模式
* */
int layerId5 = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
Paint paint5 = getPaint();
paint5.setColor(getResources().getColor(R.color.colorPrimary));
canvas.drawCircle(500, 800, 100, paint5);
paint5.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
paint5.setColor(getResources().getColor(R.color.colorAccent));
if (Build.VERSION.SDK_INT >= 21)
//API 21以上
canvas.drawRoundRect(500, 800, 600, 950, 10, 10, paint5);
paint5.setXfermode(null);
canvas.restoreToCount(layerId5);
}
public Paint getPaint() {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(5);
return paint;
}
}

/** [0, 0] */
CLEAR (0),
/** [Sa, Sc] */
SRC (1),
/** [Da, Dc] */
DST (2),
/** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
SRC_OVER (3),
/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
DST_OVER (4),
/** [Sa * Da, Sc * Da] */
SRC_IN (5),
/** [Sa * Da, Sa * Dc] */
DST_IN (6),
/** [Sa * (1 - Da), Sc * (1 - Da)] */
SRC_OUT (7),
/** [Da * (1 - Sa), Dc * (1 - Sa)] */
DST_OUT (8),
/** [Da, Sc * Da + (1 - Sa) * Dc] */
SRC_ATOP (9),
/** [Sa, Sa * Dc + Sc * (1 - Da)] */
DST_ATOP (10),
/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
XOR (11),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
DARKEN (12),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
LIGHTEN (13),
/** [Sa * Da, Sc * Dc] */
MULTIPLY (14),
/** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
SCREEN (15),
/** Saturate(S + D) */
ADD (16),
OVERLAY (17);
Android底層開發之耳機插拔與音頻通道切換實例
Android底層開發之耳機插拔與音頻通道切換實例 由於使用的是耳機 麥克分離式的耳機,所以要分別上報事件。在Android系統層耳機插孔的檢測是基於/
Android Studio 引用so文件
最近在使用Android Studio 進行開發一款應用,涉及到新浪的登錄,但是新浪登錄的sdk需要引用so文件,用Studio找了半天沒找到合適的方法,不想
EasyPusher直播推送中用到的緩沖區設計和丟幀原理
問題描述我們在開發直播過程中,會需要用到直播推送端,推送端將直播的音視頻數據推送到流媒體服務器或者cdn,再由流媒體服務器/CDN進行視頻的轉發和分發,提供給客戶端進行觀
超酷炫的Android碎紙機效果推薦
在Android開發中,有時候可能會要用到碎紙機的效果,今天小編為大家整理好代碼,一起來看看吧。首先來看下效果圖實例代碼xml<com.ldoublem.Paper