Android 自定义Dialog 实现缩放功能

为了实现点击图片 利用Dialog弹出所点击的图片,然后可以实现Dialog中图片的缩放功能。如下图所示。

gif有点模糊,大概就是这样的功能,进入Dialog中之后,可以单指拖动,双指放大,单击退出。

Dialog布局如下:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:id="@+id/dialog_pic"
    android:layout_height="match_parent"
    >

    <ImageView
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:id="@+id/image_bigpic"
        android:scaleType="matrix"
        android:layout_height="match_parent" />

</RelativeLayout>

此布局中其他参数都不是很重要,主要的就是android:scaleType="matrix" 这个是让imageview响应后面代码的关键,所以一定要是此Type。

首先是参数的定义:

    private android.graphics.Matrix matrix=new android.graphics.Matrix();
    private android.graphics.Matrix saveMatrix=new android.graphics.Matrix();
    private static final int NONE=0;//三种模式
    private static final int DRAG=1;
    private static final int ZOOM=2;
    private  Boolean MOVE=false;//是否移动
    private int mode=NONE;//模式
    private PointF startPoint=new PointF();//第一个按下的点
    private PointF midPoint=new PointF();//二个点的重心
    private float oriDis=1f;//二点之间的距离

接着是关键函数的定义:

    private float distance(MotionEvent event){ //计算二点之间的距离,勾股定理
        float x=event.getX(0)-event.getX(1);
        float y=event.getY(0)-event.getY(1);
        return Float.valueOf(String.valueOf(Math.sqrt(x*x+y*y)));
    }

    private PointF middle(MotionEvent event){  //简单数学
        float x=event.getX(0)+event.getX(1);
        float y=event.getY(0)+event.getY(1);
        return new PointF(x/2,y/2);
    }

接着就是对Dialog的设置代码:(此部分只对我可用,其他人要用,则需另改参数,大致意思就是把刚才的布局填充到这个Dialog中,再用Glide把图片放进去)

final AlertDialog.Builder builder=new AlertDialog.Builder(mContent,
                                      R.style.Theme_AppCompat_Light_NoActionBar);
final Dialog dialog=new Dialog(mContent);
dialog.setContentView(R.layout.dialog_bigpic);
final ImageView imageView=(ImageView)dialog.findViewById(R.id.image_bigpic);
Glide.with(mContent).load(OverAllObject.getImageUrl(commenttTitle.url)).into(imageView);

接着就是关键部分设置Dialog的触摸监听:

imageView.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            switch (event.getAction()&MotionEvent.ACTION_MASK){//二个参数,分别是同时单点触屏和多点触屏用于响应
                                case MotionEvent.ACTION_DOWN:   //单个手指时
                                    matrix.set(imageView.getImageMatrix());  //获取此时的Image的Matrix
                                    saveMatrix.set(matrix);                  //把此时的matrix存起来
                                    startPoint.set(event.getX(),event.getY());    //获取开始的点
                                    mode=DRAG;                              //设置模式为DRAG
                                     break;
                                case MotionEvent.ACTION_POINTER_DOWN:  //多个手指时
                                    oriDis=distance(event);           //计算此时二指头距离
                                    if(oriDis>10f){
                                        saveMatrix.set(matrix);          //保存此时的matrix
                                        midPoint=middle(event);          //计算中间距离
                                        mode=ZOOM;                       //设置zoom模式
                                    }

                                    break;

                                case MotionEvent.ACTION_UP:
                                case MotionEvent.ACTION_POINTER_UP:  //单个,多个手指离开屏幕时
                                    if(mode==DRAG&&!MOVE){          //如果是点了一下,没有移动则关闭dialog
                                        dialog.dismiss();
                                    }
                                    mode=NONE;
                                    MOVE=false;
                                    break;

                                case MotionEvent.ACTION_MOVE:    //手指移动时
                                    MOVE=true;
                                    if(mode==DRAG){
                                        matrix.set(saveMatrix);             //把之前保存的matrix设为现在的,再调用posttranslate进行位移
                                        matrix.postTranslate(event.getX()-startPoint.x,event.getY()-startPoint.y);
                                    }else if (mode==ZOOM){

                                        float newDist=distance(event);
                                        if(newDist>10f){                     
                                            matrix.set(saveMatrix);                
                                            float scale=newDist/oriDis;         //根据初始手指距离和现在手指距离的比值来确定缩放倍数,
                                            matrix.postScale(scale,scale,midPoint.x,midPoint.y);    //(x轴缩放倍数,y轴缩放倍数,缩放重心x,缩放重心y)
                                        }

                                    }

                                    break;

                            }

                            imageView.setImageMatrix(matrix);//应用于布局
                            return true;
                        }
                    });
                    
                    dialog.show();
                    

如何这样显示布局有点问题可以自己再修改。

end:不一定要是Dialog中,Activity中都可以实现这个,首先实现布局,获取到Imageview,接着对他进行触摸监听就可以了

发布了73 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/daguniang123/article/details/88943311
今日推荐