編輯:關於Android編程
首先在寫這篇博客的時候,需要說明我是參考了那篇博文給我的靈感:
詳解Paint的setXfermode(Xfermode xfermode)
其次呢,在寫這篇博文的時候呢也避免不了抱怨啊。網上其他的關於Xfermode介紹的大部分都是google官方文檔中屬性的含義,都很雷同估計都是翻譯過來的
我想說的是就不能有點原創嗎?
so,我決定寫這篇文章:
一是抒發我心中的糾結; 二是抒發這麼多天下文章一大抄就是沒有自己出的文章; 三是抄就抄吧,也要加入自己的感悟把;
四是記錄一下,以免以後忘記;另外呢,之前我准備參考源碼來寫這篇文章的,但是我下載之後沒有下載到,android5.1下載的samples裡面沒有找到apidemo,不知道怎麼回事,如果有童鞋知道是怎麼回事的,可以和我說說,並且下載下載android5.1的sdk速度飛速啊,但是5.0之後的sdk基本上無響應,下載不了。
下面進入正題吧:
不免俗套的貼上google官方ApiDemo中Graphics中Xfermode截圖:
糾結了2天終於弄出來的
最令人氣憤是你看著其他人博客然後想做google官方屬性的出的效果,但是愣是沒有做出來效果,我這暴脾氣,非要弄出來。就是比別人糾結。
於是乎有了這篇博文。
有可能是我大腦不行,給出大伙看看其他博文的寫法:
他們都是 XxxView extends ImageView然後寫的,但是關鍵點都沒有介紹出來。我呢下面會給大家介紹最簡單直接的做法,為了方便大伙看明白,簡單有效才是王道!!
,只是給大伙對比下,其實我們只需要簡簡單單的怎麼用而不是把全套寫法代碼都貼出來。點到即止,同時也要讓大伙知道怎麼用。
此處省略百度一大堆文章,全是代碼根本不知道他們要說的主要思想是什麼……..,不是灌水,不是攻擊,只是給大伙借鑒
下面真正是正文了啊:大伙注意了。
對於官方文檔的xfermode我們只是看到兩個類似層的圖片
其實和photoshop中的圖層一樣;
一個是原始圖層,另一個是遮罩層;
我把整個View的畫布設置為綠色了,為了方便大家觀看效果
canvas.drawColor(Color.GREEN);//畫布設為綠色
先上效果圖吧,嘿嘿蒼老師的頭像。
看完正確運行出來的效果,那麼給大家看看錯誤運行出來的效果:
是我的蒼老師,也是大家的蒼老師
這個是為什麼呢
最後參照文章開頭的鏈接給大伙看的必須要設置:
//將繪制操作保存到新的圖層(離屏緩存)
canvas.saveLayer(0,0,300,300, null,Canvas.ALL_SAVE_FLAG);
方法:
public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags)
大伙不要小看這個方法,我們必須設置將繪制操作保存到新的圖層,不然就會出現蒼老師頭像顯示不正常的情況
當然最後還要還原畫布
// 還原畫布
canvas.restoreToCount(sc);
canvas顧名思義是畫布。所有的繪制操作都發生在這張畫布上,當然當我們要使用多個圖片疊加等的情況我們就要使用“層”了,就如百度地圖或是高德地圖,他們在地圖上面添加新的事物,如線路,興趣點的時候都是用到了層Layer。
當然Canvas給我們提供了層支持;這些Layer是按照棧結構來管理的,後進先出的順序顯示;
當Layer入棧的時候,那麼後續的drawXXXX操作都發生在這個Layer層上面。而Layer退棧時,就會把本層繪制的圖像“繪制”到上層或是Canvas上,在復制Layer到Canvas上時,可以指定Layer的透明度(Layer),這是在創建Layer時指定的:
public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
我們這篇就不說明saveLayerAplha了。大伙可以自己使用
那麼說這麼多,有人看博文肯定說代碼呢,稍等,客官馬上就來咯:
當然Xfermode網上很多文章都寫了相關屬性介紹的含義,當然我做這個的時候是按照官方給出圖片做的效果。意思呢,可以意會。如果我說了,大伙又迷糊了。哈哈哈哈,這也是我的風格。
那麼我所有的操作都在onDraw()函數體裡面寫了啊。至於性能方面不是我這篇文章所討論的。可以不用在onDraw裡面new對象操作,可以提高性能啥的。
當然自定義view避免不了,先測量下啦。為了簡單直接這樣:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width=MeasureSpec.getSize(widthMeasureSpec);
int height=MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width,height);
}
最後貼上onDraw裡面的代碼,全部在這了:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GREEN);//設畫布綠色
canvas.translate(20,20);//移動畫布
// 原始圖片
Bitmap src = BitmapFactory.decodeResource(getResources(), R.mipmap.cangcang);
// 圖片的遮罩
Bitmap mask=Bitmap.createBitmap(300, 300, src.getConfig());
Canvas cc=new Canvas(mask);
cc.drawCircle(150,150,150,mPaint);
/*
* 離屏緩存
* Layer層的寬和高要設定好,不然會出現有些部位不再層裡面,你的操作是不對這些部位起作用的
*/
int sc = canvas.saveLayer(0,0,300,300, null, Canvas.ALL_SAVE_FLAG);
// 先繪制dis目標圖
canvas.drawBitmap(src, 0, 0, mPaint);
// 設置混合模式 (只在源圖像和目標圖像相交的地方繪制目標圖像)
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
// 再繪制src源圖
canvas.drawBitmap(mask, 0, 0, mPaint);
// 還原混合模式
mPaint.setXfermode(null);
// 還原畫布
canvas.restoreToCount(sc);
}
那麼其他的xfermode屬性大家可以自己嘗試。前提是Layer的寬度和高度大家要控制好,其他都大同小異。
實現定時器有很多種方式,在這裡我簡單的介紹幾種方式 (1)使用Handler + Runnable的方式 復制代碼 代碼如下: Handler handler = new
實現效果如下: 因為是通知欄,那麼點擊後如何傳遞呢?定義一個廣播,當點擊的時候就發送此廣播,注冊此廣播。 收到廣播後就取消下載。關鍵代碼在這裡。 Bro
Android插件開發初探 對於Android的插件化其實已經討論已久了,但是市面上還沒有非常靠譜成熟的插件框架供我們使用。這裡我們就嘗試性的對比一下Java中,我們使用
在開發中往往有要獲取聯系人列表的功能,但是這次卻不是獲取聯系人列表,而是在聯系人列表點擊單個聯系人,獲取單個聯系人的姓名和電話,並設置在指定的輸入框內,方便用戶的使用;以