Android自定義控制元件打造放大鏡效果
阿新 • • 發佈:2019-02-19
上週沒啥事,想到以前看到過一個放大鏡的效果,雖然感覺這個效果沒什麼用,但是覺得還是挺酷炫的,所以就花了點時間,做了一個放大鏡的自定義控制元件。
首先說說我的思路,需要做到放大效果,我的想法是利用矩陣Matrix將圖片進行放大和平移,然後再根據放大鏡顯示的位置,顯示對應的放大位置。所以步驟如下:
先做一個可以跟隨手指移動的控制元件,重寫onTouchEvent方法,程式碼如下:
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK ) { case MotionEvent.ACTION_DOWN: locationX = getX(); locationY = getY(); downX = event.getRawX(); downY = event.getRawY(); break; case MotionEvent.ACTION_MOVE://隨手移動,getRawX()與getX()有區別 setX(locationX+(event.getRawX()-downX)); setY(locationY+(event.getRawY()-downY)); invalidate(); break; } return true; }
這樣控制元件就會跟隨手指的移動而移動,然後移動的時候,利用invalidate()放大呼叫onDraw方法進行畫圖繪製。onDraw裡繪製了放大鏡的底層背景,中間顯示的放大圖片,已經上層的濾鏡效果。程式碼如下:
@Override protected void onDraw(Canvas canvas) { if(bm!=null) { Paint paintBg = new Paint();//背景防止載入自帶透明的圖片時,放大圖片後面能看到原來的圖片 paintBg.setAntiAlias(true);//抗鋸齒 paintBg.setColor(Color.parseColor("#ffffff")); canvas.drawCircle(magnifierLen/2,magnifierLen/2,magnifierLen/2,paintBg); Paint paint = new Paint(); paint.setAntiAlias(true);//抗鋸齒 paint.setShader(bitmapShader);//bitmapShader畫圓形圖片 //建立矩陣,縮放平移圖片 Matrix matrix = new Matrix(); matrix.setScale(scaleX, scaleY); matrix.postTranslate(-(scaleX*getX()+(scaleX-1)*magnifierLen/2), -(scaleY*getY()+(scaleY-1)*magnifierLen/2));//為了放大效果是取放大鏡中心開始放大的效果 bitmapShader.setLocalMatrix(matrix);//利用bitmapShader畫圓形圖片 canvas.drawCircle(magnifierLen/2,magnifierLen/2,magnifierLen/2,paint); Paint paintShade = new Paint();//外層遮罩 paintShade.setAntiAlias(true);//抗鋸齒 paintShade.setColor(Color.parseColor(magnifierColor)); paintShade.setAlpha(magnifierAlpha); canvas.drawCircle(magnifierLen/2,magnifierLen/2,magnifierLen/2,paintShade); } }
這樣核心程式碼就完成了,然後中間需要用到很多可配置的設定,比如放大鏡的初始位置,初始大小,放大倍數,初始濾鏡的透明度等等。於是我們建立一個建立者,用於構造放大鏡例項,程式碼如下:
/** * 建立建造者,用於構建當前物件。多用於複雜構建 */ public static class Builder { private Context context; private int initLeft=0,initTop=0;//初始位置,相對於父控制元件的位置 private int viewW=300,viewH=300;//控制元件寬高 private float scaleX=1.5f,scaleY=1.5f;//x,y的放大倍數 private String magnifierColor = "#ff0000";//放大鏡顏色 private int magnifierAlpha = 32;//放大鏡透明度 private ViewGroup rootVg; public Builder(Context context) { this.context = context; } public Builder intiLT(int initLeft,int initTop) { if(initLeft>0) this.initLeft = initLeft; if(initTop>0) this.initTop = initTop; return this; } public Builder viewWH(int viewW,int viewH) { this.viewW = viewW; this.viewH = viewH; return this; } public Builder rootVg(ViewGroup rootVg) { this.rootVg = rootVg; return this; } public Builder scale(float scale)//放大鏡放大倍數 { this.scaleX = scale; this.scaleY = scale; return this; } public Builder color(String color) { this.magnifierColor = color; return this; } public Builder alpha(int alpha) { if(alpha>=200) { this.magnifierAlpha = 200; } else if(alpha<0) { this.magnifierAlpha = 0; } else { this.magnifierAlpha = alpha; } return this; } public MagnifierView build() { return new MagnifierView(this,context); } }
這樣放大鏡的自定義控制元件基本完成了,講的可能不是很詳細,具體還是閱讀原始碼理解的更深刻,原始碼傳送門點選連結。
最後實現效果如下: