最近在寫一個相似「圍住神經貓」的應用,如今須要給一個能夠移動的Paint元素指定一張圖片,以下圖,要把黃點改爲其餘圖片;android
Paint所在的類繼承於SurfaceView,SurfaceView能夠直接從內存等硬件接口獲取圖像數據,速度很快;而後再implements 一個OnTouchListener接口來監聽觸摸事件;算法
最初找到不少方法,給playground添加圖片、給Activity添加圖片、另寫一個工具類加載圖片。。。都很繁瑣,並且代碼加進去運行的時候老是Crash,多是本身操做存在問題,這些方法都沒有實現想要的效果;canvas
後來發現,只須要在redraw() 函數中添加幾行代碼~app
圖像繪製函數redraw() 的代碼是這樣寫的,功能是設置路障圓點、路徑圓點和一個移動圓點的顏色:函數
public void redraw(){ // 繪製
Canvas c = getHolder().lockCanvas(); //c.drawColor(Color.LTGRAY); // 繪製淺灰色背景界面
c.drawColor(Color.DKGRAY); // 繪製淺灰色背景界面 //c.drawBitmap(resizeBitmap(xrd, getWidth(), getHeight()), 0, 0, null);// 設置背景圖片s
size = (ROW / 3) * (getWidth() / 9 - WIDTH);// 將格子向下平移 // 繪製全部的點到Activity
Paint paint = new Paint(); // 開啓畫面抗鋸齒,必須寫在點生成以前
paint.setFlags(Paint.ANTI_ALIAS_FLAG); for (int i = 0; i < ROW-1; i++) { // 進行奇數行\偶數行的判斷
int offset = 0; if (i % 2 != 0) { offset = WIDTH /2; // 偶數行寬度縮進半個點
} for (int j = 0; j < COL-1; j++) { Dot one = getDot(j, i); switch (one.getStatus()) { case Dot.STATUS_OFF: //paint.setColor(0xFFEEEEEE);// 徹底不透明,顏色淺灰色 //paint.setColor(Color.GRAY);// 淺灰色
paint.setColor(Color.rgb(165, 165, 165)); // 設定好顏色以後,開始在 canvas上面繪製, RectF是繪製 橢圓,循環繪製100個
c.drawOval(new RectF(one.getX()*WIDTH+offset, one.getY()*WIDTH, //右側邊界
(one.getX()+1)*WIDTH+offset, (one.getY()+1)*WIDTH), paint); break; case Dot.STATUS_ON: // 路障顏色 //paint.setColor(0xFFFFAA00); // 0xFF透明度 FFAA00黃色
paint.setColor(Color.rgb(147, 117, 27));
c.drawOval(new RectF(one.getX()*WIDTH+offset, one.getY()*WIDTH, //右側邊界
(one.getX()+1)*WIDTH+offset, (one.getY()+1)*WIDTH), paint); break; case Dot.STATUS_IN:
paint.setColor(Color.YELLOW); c.drawOval(new RectF(one.getX()*WIDTH+offset, one.getY()*WIDTH, //右側邊界
(one.getX()+1)*WIDTH+offset, (one.getY()+1)*WIDTH), paint); // paint.setColor(getResources().getColor(android.R.color.black));
break; default: break; } } }
如今只需在redraw()函數的 case Dot.STATUS_IN: 之下寫入以下幾行代碼便可:工具
Resources res = getResources(); Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.happy_huge); Rect rect = new Rect(0, bmp.getHeight(), bmp.getWidth(), 0); c.drawBitmap(bmp,null, new RectF(one.getX()*WIDTH+offset, one.getY()*WIDTH, (one.getX()+1)*WIDTH+offset, (one.getY()+1)*WIDTH), paint);
記得圖片要先加載到drawable中,這裏已把圖片處理爲透明的png格式;spa
這段代碼的原理是:實例化一個Resources,經過Bitmap讀取Resources和R.drawable,而後使用Rect類設定範圍,再經過Canvas的drawBitmap()函數繪製出來就能夠了~ code
按下Ctrl+F11;blog
需求已然實現,目前將近500行代碼,不過我打算繼續實現以下效果:繼承
一、自定義難易度;
二、圍住以後彈窗加載一張圖片;
三、把移動的元素改爲動態gif。
雖然我一次就把他圍住了,但那是由於本身瞭解代碼算法的緣故,不然是沒法一次性圍住的,不過能夠增長隨機性,這樣就算了解算法也沒法百分百圍住,搭配漫畫表情更增新趣味~