天天看點

Android自定義控件打造放大鏡效果

      上周沒啥事,想到以前看到過一個放大鏡的效果,雖然感覺這個效果沒什麼用,但是覺得還是挺酷炫的,是以就花了點時間,做了一個放大鏡的自定義控件。

       首先說說我的思路,需要做到放大效果,我的想法是利用矩陣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);
        }
    }
           

       這樣放大鏡的自定義控件基本完成了,講的可能不是很詳細,具體還是閱讀源碼了解的更深刻,源碼傳送門點選連結。

最後實作效果如下:

Android自定義控件打造放大鏡效果