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);
        }
    }

       这样放大镜的自定义控件基本完成了,讲的可能不是很详细,具体还是阅读源码理解的更深刻,源码传送门点击链接

最后实现效果如下:

猜你喜欢

转载自blog.csdn.net/chen12521252/article/details/81449080