package com.example.myimageview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class MyImageView extends ImageView{
        Matrix matrix = new Matrix();  
        Matrix savedMatrix = new Matrix();  
        /**位图对象*/  
        private Bitmap bitmap = null;  
        /** 屏幕的分辨率*/  
        private DisplayMetrics dm;  
      
        /** 最小缩放比例*/  
        float minScaleR = 1.0f;  
          
        /** 最大缩放比例*/  
        static final float MAX_SCALE = 15f;  
        /** 初始状态*/  
        static final int NONE = 0;  
        /** 拖动*/  
        static final int DRAG = 1;  
        /** 缩放*/  
        static final int ZOOM = 2;  
        /** 当前模式*/  
        int mode = NONE;  
        /** 存储float类型的x,y值,就是你点下的坐标的X和Y*/  
        PointF prev = new PointF();  
        PointF mid = new PointF();  
        float dist = 1f;  
        public MyImageView(Context context) {  
            super(context);  
            setupView();  
        }  
          
        public MyImageView(Context context, AttributeSet attrs) {  
            super(context, attrs);  
            setupView();  
        }  
          
          
        public void setupView(){  
            Context context = getContext();  
            //获取屏幕分辨率,需要根据分辨率来使用图片居中  
            dm = context.getResources().getDisplayMetrics();  
              
            //根据MyImageView来获取bitmap对象  
            BitmapDrawable bd = (BitmapDrawable)this.getDrawable();  
            if(bd != null){  
                bitmap = bd.getBitmap();  
            }  
    
            //设置ScaleType为ScaleType.MATRIX,这一步很重要  
            this.setScaleType(ScaleType.MATRIX);  
            this.setImageBitmap(bitmap);  
              
            //bitmap为空就不调用center函数  
            if(bitmap != null){  
                center(true, true);  
            }  
            this.setImageMatrix(matrix);  
            this.setOnTouchListener(new OnTouchListener() {  
                @Override  
                public boolean onTouch(View v, MotionEvent event) {  
                     switch (event.getAction() & MotionEvent.ACTION_MASK) {  
                        // 主点按下  
                        case MotionEvent.ACTION_DOWN:  
                            savedMatrix.set(matrix);  
                            prev.set(event.getX(), event.getY());  
                            mode = DRAG;  
                            break;  
                        // 副点按下  
                        case MotionEvent.ACTION_POINTER_DOWN:  
                            dist = spacing(event);  
                            // 如果连续两点距离大于10,则判定为多点模式  
                            if (spacing(event) > 10f) {  
                                savedMatrix.set(matrix);  
                                midPoint(mid, event);  
                                mode = ZOOM;  
                            }  
                            break;  
                        case MotionEvent.ACTION_UP:{  
                            break;  
                        }  
                        case MotionEvent.ACTION_POINTER_UP:  
                            mode = NONE;  
                            //savedMatrix.set(matrix);  
                            break;  
                        case MotionEvent.ACTION_MOVE:  
                            if (mode == DRAG) {  
                                matrix.set(savedMatrix);  
                                matrix.postTranslate(event.getX() - prev.x, event.getY()  
                                        - prev.y);  
                            } else if (mode == ZOOM) {  
                                float newDist = spacing(event);  
                                if (newDist > 10f) {  
                                    matrix.set(savedMatrix);  
                                    float tScale = newDist / dist;  
                                    matrix.postScale(tScale, tScale, mid.x, mid.y);  
                                }  
                            }  
                            break;  
                        }  
                        MyImageView.this.setImageMatrix(matrix);  
                        CheckView();  
                        return true;  
                }  
            });  
        }    
        /**
         * 横向、纵向居中
         */  
        protected void center(boolean horizontal, boolean vertical) {  
            Matrix m = new Matrix();  
            m.set(matrix);  
            RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());  
            m.mapRect(rect);  
      
            float height = rect.height();  
            float width = rect.width();  
      
            float deltaX = 0, deltaY = 0;  
      
            if (vertical) {  
                // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移  
                int screenHeight = dm.heightPixels;  
                if (height < screenHeight) {  
                    deltaY = (screenHeight - height) / 2 - rect.top;  
                } else if (rect.top > 0) {  
                    deltaY = -rect.top;  
                } else if (rect.bottom < screenHeight) {  
                    deltaY = this.getHeight() - rect.bottom;  
                }  
            }  
      
            if (horizontal) {  
                int screenWidth = dm.widthPixels;  
                if (width < screenWidth) {  
                    deltaX = (screenWidth - width) / 2 - rect.left;  
                } else if (rect.left > 0) {  
                    deltaX = -rect.left;  
                } else if (rect.right < screenWidth) {  
                    deltaX = screenWidth - rect.right;  
                }  
            }  
            matrix.postTranslate(deltaX, deltaY);  
        }  
          
        /**
         * 限制最大最小缩放比例,自动居中
         */  
        private void CheckView() {  
            float p[] = new float[9];  
            matrix.getValues(p);  
            if (mode == ZOOM) {  
                if (p[0] < minScaleR) {  
                    //Log.d("", "当前缩放级别:"+p[0]+",最小缩放级别:"+minScaleR);  
                    matrix.setScale(minScaleR, minScaleR);  
                }  
                if (p[0] > MAX_SCALE) {  
                    //Log.d("", "当前缩放级别:"+p[0]+",最大缩放级别:"+MAX_SCALE);  
                    matrix.set(savedMatrix);  
                }  
            }  
            center(true, true);  
        }  
          
        /**
         * 两点的距离
         */  
        private float spacing(MotionEvent event) {  
            float x = event.getX(0) - event.getX(1);  
            float y = event.getY(0) - event.getY(1);  
            return FloatMath.sqrt(x * x + y * y);  
        }  
        /**
         * 两点的中点
         */  
        private void midPoint(PointF point, MotionEvent event) {  
            float x = event.getX(0) + event.getX(1);  
            float y = event.getY(0) + event.getY(1);  
            point.set(x / 2, y / 2);  
        }  
    }

自定义ImageView的更多相关文章

  1. Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示

    Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过 ...

  2. 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果

    首先呢,还是一贯作风,我们先来看看众多应用中的示例:(这种效果是很常见的,可以说应用的必须品.)                搜狐客户端                               ...

  3. (一)自定义ImageView,初步实现多点触控、自由缩放

    真心佩服那些一直专注于技术共享的大神们,正是因为他们无私的分享精神,我才能每天都有进步.近日又算是仔细学了android的自定义控件技术,跟着大神的脚步实现了一个自定义的ImageView.里面涉及到 ...

  4. android自定义控件(7)-获取自定义ImageView的src属性

    创建一个自定义组件,继承 ImageView.在我的 xml 布局文件中是这样设置的: <Mycomponent android:src="@drawable/my_test_imag ...

  5. Android -- 自定义ImageView(圆形头像)

    1.  原图

  6. 自定义ImageView回调实现手动改变圆环大小

    //-----------------自定义MyView继承Imageview------------------------------- package com.bw.yuanhuan; impo ...

  7. Android 自定义ImageView支持缩放,拖拽,方便复用

    今天刚发了一篇关于ImageView的缩放和拖拽的博客,然后我想了下,将他自定义下,方便我们来复用这个imageView,效果我就不多说了,http://blog.csdn.net/xiaanming ...

  8. Android自定义ImageView圆形头像

    效果图: 代码如下: RoundImageView.java import cn.comnav.evaluationsystem.R; import android.content.Context; ...

  9. 自定义ImageView的MainActivity

    package com.baidu.lianximyview; import com.example.myimageview.MyImageView; import android.os.Bundle ...

随机推荐

  1. C# Socket编程(4)初识Socket和数据流

    经过前面基础知识作为背景,现在对Socket编程进行进一步的学习.在System.Net.Socket命名空间提供了Socket类,利用该类我们可以直接编写Socket的客户端和服务的的程序.但是直接 ...

  2. listview某一项不可点击

    listview 整个都不可操作 listview.setEnable(false); listview 某一项不可点击 重写 isEnable()方法,在方法内部判断position,不可点击的项 ...

  3. android fragment 博客 学习记录

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 上篇博客中已经介绍了Fragment产生原因,以及一些基本的用法和 ...

  4. 【转】android fragment 博客 学习

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37970961 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fra ...

  5. centos7 安装mariaDB 以及 phpmyadmin的安装

    centos7 安装mariaDB 以及 phpmyadmin的安装 一:安装mariadb, mariadb 是 mysql 的一个分支,基本和mysql一样的 1. yum -y install ...

  6. css3中clip属性

    clip 属性用来设置元素的形状.用来剪裁绝对定位元素. 当一幅图像的尺寸大于包含它的元素时,"clip" 属性允许规定一个元素的可见尺寸,这样此元素就会被修剪并显示在这个元素中. ...

  7. 企业用户选择Java多于.NET的 5个原因

    .NET 和 Java 是当今社会最受欢迎的两种编程语言, 长期的发展和强大的功能使他们足以在编程界立足. 十余年的争论也没得到结果的一个话题就是——他们哪个更好一些? 今天, 我们不再去讨论JAVA ...

  8. Thread 总结

    进程:是一个正在执行的程序 每一个进程执行都有一个执行顺序.该顺序是一个执行路劲,后者叫一个控制单元. 线程:就是进程中的一个独立控制单元. 线程在控制着进程的执行 一个进程中至少有个一个线程 Jav ...

  9. 118. 119. Pascal's Triangle -- 杨辉三角形

    118. Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, ...

  10. 5月4日课堂内容:for循环的穷举、迭代

    一.for循环拥有两类: 1.穷举: 把所有可能的情况都走一遍,使用if条件筛选出来满足条件的情况. 2.迭代: 从初始情况按照规律不断求解中间情况,最终推导出结果. 二.穷举练习 1.单位给发了一张 ...