編輯:關於Android編程
AvoidXfermode 指定了一個顏色和容差,強制Paint避免在它上面繪圖(或者只在它上面繪圖)。
PixelXorXfermode 當覆蓋已有的顏色時,應用一個簡單的像素異或操作。
PorterDuffXfermode 這是一個非常強大的轉換模式,使用它,可以使用圖像合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas圖像進行交互。
我們今天的呈現就是在PorterDuffXfermode 這部分實現的
PorterDuff.Mode為枚舉類,一共有16個枚舉值分別是
1.PorterDuff.Mode.CLEAR
所繪制不會提交到畫布上。
2.PorterDuff.Mode.SRC
顯示上層繪制圖片
3.PorterDuff.Mode.DST
顯示下層繪制圖片
4.PorterDuff.Mode.SRC_OVER
正常繪制顯示,上下層繪制疊蓋。
5.PorterDuff.Mode.DST_OVER
上下層都顯示。下層居上顯示。
6.PorterDuff.Mode.SRC_IN
取兩層繪制交集。顯示上層。
7.PorterDuff.Mode.DST_IN
取兩層繪制交集。顯示下層。
8.PorterDuff.Mode.SRC_OUT
取上層繪制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下層繪制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下層非交集部分與上層交集部分
11.PorterDuff.Mode.DST_ATOP
取上層非交集部分與下層交集部分
12.PorterDuff.Mode.XOR
異或:去除兩圖層交集部分
13.PorterDuff.Mode.DARKEN
取兩圖層全部區域,交集部分顏色加深
14.PorterDuff.Mode.LIGHTEN
取兩圖層全部,點亮交集部分顏色
15.PorterDuff.Mode.MULTIPLY
取兩圖層交集部分疊加後顏色
16.PorterDuff.Mode.SCREEN
取兩圖層全部區域,交集部分變為透明色
在將這一系列的效果之前我們先把我們昨天畫圓的例子改一下
public class TestView extends View {
Paint paint;
Context context;
Bitmap bitmap;
public TestView(Context context) {
super(context);
this.context = context;
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
paint = new Paint();
// paint.setColor(getResources().getColor(R.color.SlateBlue));
paint.setColor(getResources().getColor(R.color.Gold));
paint.setStrokeWidth(3); //粗細
paint.setAntiAlias(true); //設置畫筆為無鋸齒
bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.bg);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("--->onDraw", "onDraw()");
// canvas.drawCircle(0, 0, 90, paint);
canvas.drawBitmap(bitmap,0,0,paint);
canvas.drawCircle(100, 100, 90, paint);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
Log.d("--->onLayout", "changed = " + changed + " left = " + left + " top = " + top + " right = " + right + " bottom " + bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.d("--->onMeasure", " widthMeasureSpec =" + widthMeasureSpec + " heightMeasureSpec = " + heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
我們在畫圓之後又畫了個背景圖,效果如下:
在我們的圓下面有一個妹子,並且圓是會蓋掉妹子那一塊圓的塗抹面積的。
那我們把onDraw()方法裡執行的順序換一下呢?
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("--->onDraw", "onDraw()");
// canvas.drawCircle(0, 0, 90, paint);
canvas.drawCircle(100, 100, 90, paint);
canvas.drawBitmap(bitmap,0,0,paint);
}
如果改成這樣,我們的圓就沒了(效果不貼了)
利用PorterDuff.Mode就可以很好的解決這個問題當然,可能你得多繪制一次然後再做覆蓋的操作了,所以在你決定先畫什麼後畫什麼之前一定理清誰在前誰在後
本來想寫個大致的例子,但是想想16個都好麻煩,就拿了一個市面上比較多的圖吧
上面的代碼不變,我們在新建一個Canvas然後把他裡面話一點東西,來模擬我們想要的效果。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("--->onDraw", "onDraw()");
// canvas.drawCircle(0, 0, 90, paint);
canvas.drawCircle(100, 100, 90, paint1);
canvas.drawBitmap(bitmap, 120, 120, paint1);
Canvas canvas1=new Canvas(bitmap);
Paint paint2=new Paint();
paint2.setColor(getResources().getColor(R.color.LightPink));
paint2.setTextSize(50);
canvas1.drawText("Ezreal", 0, 200, paint2);
canvas1.drawText("Malzahar ",0,300,paint2);
}
效果如下:
P1.我們用畫布又畫了2個字。那麼我們來試下各種效果(分析和方法,會分兩部分羅列)
平移:1.void translate(float dx, float dy)<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPsa90sayzsr9o7oyuPbX+LHqteNY1f3P8tPSIFnV/c/yz8KjrLi6yv23tNauoaM8L3A+DQo8cD48c3Ryb25nPtD916o8L3N0cm9uZz6jujxiciAvPg0KMS52b2lkIHJvdGF0ZShmbG9hdCBkZWdyZWVzKTxiciAvPg0KMi52b2lkIHJvdGF0ZSAoZmxvYXQgZGVncmVlcywgZmxvYXQgcHgsIGZsb2F0IHB5KTwvcD4NCjxwPtD916qyzsr9o7rS1Nf4serUrbXjo6jX88nPo6nOqtD916rW0NDE16pkZWdyZWVztsijqNX9tcTOqtX916qjrLi6tcTOqre016qjqaOscHgscHnOqtLUKHB4LHB5Kc6q1tDQxND916pkZWdyZWVztsguPC9wPg0KPHA+PHN0cm9uZz7L9bfFPC9zdHJvbmc+o7o8YnIgLz4NCjEucHVibGljIHZvaWQgc2NhbGUgKGZsb2F0IHN4LCBmbG9hdCBzeSk8YnIgLz4NCjIucHVibGljIGZpbmFsIHZvaWQgc2NhbGUgKGZsb2F0IHN4LCBmbG9hdCBzeSwgZmxvYXQgcHgsIGZsb2F0IHB5KTwvcD4NCjxwPsv1t8Wyzsr9o7pzeM6qy67Gvcv1t8WjrDGx7cq+srux46OstPPT2jG3xbTzo6zQodPrMcv10KGjqLi6tcTO0sO7ytS5/aOpo7tzedTyse3KvrS51rGjrMLfvK3NrMuuxr0uPC9wPg0KPHA+PHN0cm9uZz7QscfQPC9zdHJvbmc+o7o8L3A+DQo8cD4xLnZvaWQgc2tldyAoZmxvYXQgc3gsIGZsb2F0IHN5KTwvcD4NCjxwPtCxx9Cyzsr9o7pzeDq9q7utsrzU2ni3vc/yyc/H49Cxz+DTprXEvce2yKOsc3jH49Cxvce2yLXEdGFu1rWju3N5Or2ru62yvNTaedbht73P8snPx+PQsc/g06a1xL3HtsijrHN5zqrH49Cxvce2yLXEdGFu1rUuPC9wPg0KPGhyIC8+DQo8cD5QMi7Ktc/W0tS8sL3iys2jujwvcD4NCjxwPjEuxr3SxqO6PGJyIC8+DQo8aW1nIGFsdD0="這裡寫圖片描述" src="/uploadfile/Collfiles/20151230/20151230092039134.png" title=""http://zz.2cto.com/seo/" target="_blank" class="keylink">seorMzAwo6xZ1/ix6iszMDCjqaGjPC9wPg0KPHA+tavKxyDQp7n7ysfV4tH5wvCjvzwvcD4NCjxwPs6qwcvR6dakyLfKtcjntMvO0sPH1NnU2dPSsuC7rdK7uPYmbGRxdW87QWthbGkmcmRxdW87PC9wPg0KPHByZSBjbGFzcz0="brush:java;">
//並且是在平移前執行
canvas1.drawText("Akali ",200,400,paint2);
然後我們在平移之後再畫一個Katarina Du Couteau
並且跟平移前的阿卡麗是用以坐標
canvas1.drawText("Katarina Du Couteau ", 200, 400, paint2);
效果是卡特跟著整個坐標系走了而不是之前的坐標相加的結果。
所以:
1.每次調用canvas.drawXXXX系列函數來繪圖進,都會產生一個全新的Canvas畫布。
2.在Canvas與屏幕合成時,超出屏幕范圍的圖像是不會顯示出來的。
2.旋轉
我們還是回到最初的螞蚱和EZ的樣子
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d("--->onDraw", "onDraw()");
// canvas.drawCircle(0, 0, 90, paint);
canvas.drawCircle(100, 100, 90, paint1);
canvas.drawBitmap(bitmap, 120, 120, paint1);
Canvas canvas1 = new Canvas(bitmap);
Paint paint2 = new Paint();
paint2.setColor(getResources().getColor(R.color.LightPink));
paint2.setTextSize(50);
// canvas1.drawText("Akali ", 200, 400, paint2);
// canvas1.translate(300, 300);
canvas1.drawText("Ezreal", 0, 200, paint2);
canvas1.rotate(30);
canvas1.drawText("Malzahar ", 0, 300, paint2);
// canvas1.drawText("Katarina Du Couteau ", 200, 400, paint2);
}
然後把螞蚱旋轉30度,效果如圖
EZ位置沒變,螞蚱轉了,並且有一部分超出了我們的妹子Bitmap所以它不見了。
然後此時此刻,我們的阿卡麗回來了,並且在螞蚱之後
我們的啊卡裡也跟著螞蚱轉走了,說明旋轉和平移是一樣的整個位圖轉走了。
如下圖向著箭頭方向偏了30度然後創建了一個新的Canvas
3.縮放
縮放的圖我就不畫了,代碼就是canvas.scale(1, 1.5f); 就是Y方向縮放1.5f
也是重繪了一個Canvas和上面都一樣。
4.斜切
其實也就是可以實現我們的一個斜體的效果,這裡就貼一下執行效果
還有就是int save () void restore()
相對比較簡單,對堆棧的概念清晰的小伙伴一看就懂,不需要過多試驗,這裡就不明說了。
Android 有效的解決內存洩漏的問題Android內存洩漏,我想做Android 應用的時候遇到的話很是頭疼,這裡是我在網上找的不錯的資料,實例詳解這個問題的解決方案
Line靜音自拍APP“B612”是一款自拍專用APP,專門用於自拍,且不會發出快門聲。該應用使用簡單,拍照之前無需像傳統拍照軟件那
上一篇文章已經介紹了如何為RecyclerView添加FootView,在此基礎上,要添加分頁加載的功能其實已經很簡單了。 上一篇文章地址:為RecyclerView添加
ExpandableListView是一個垂直滾動顯示兩級列表項的視圖,與ListView不同的是,它可以有兩層:每一層都能夠被獨立的展開並顯示其子項。好友QQ列表,可以