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. linux环境(CentOS-6.7)下redis集群的搭建全过程

    linux环境下redis集群的搭建全过程: 使用mount命令将光盘挂载到/mnt/cdrom目录下: [root@hadoop03 ~]# mount -t iso9660 -o ro /dev/ ...

  2. LTIB常用命令2

    LTIB 编译配置选项 根据说明文档,ltib 可以通过以下的命令配置: * <verbatim># ./ltib</verbatim>          安装后第一次运行,采 ...

  3. HEVC编解码优化信息

    hevc解码GPU优化: 1.This GPU acceleration has opened up the possibility of playing a Full-HD (1080p) at 6 ...

  4. OpenCV3编程入门笔记(4)腐蚀、膨胀、开闭运算、漫水填充、金字塔、阈值化、霍夫变换

    腐蚀erode.膨胀dilate 腐蚀和膨胀是针对图像中的白色部分(高亮部分)而言的,不是黑色的.除了输入输出图像外,还需传入模板算子element,opencv中有三种可以选择:矩形MORPH_RE ...

  5. js封装,一个JS文件引用多个JS文件

    (function() { //加载   varobj =  {};   /**    * 动态加载脚本函数    * @param url 要加载的脚本路径    * @param callback ...

  6. laravel实现第三方登录

    https://github.com/laravel/socialite 这是官方的第三方登录包,支持很多国外的第三方登录 https://github.com/overtrue/socialite ...

  7. javascript之with的使用 弊端

    妹的,昨天都快写完了,一不小心点了个关闭,然后...就没有然后了 wordpress的自动保存功能咋就这么不靠谱呢 记得还在懵懂学习JavaScript基础之时,坊间便有传言“with语句是低效率语句 ...

  8. 《Java程序设计》学期总结

    <Java程序设计> 学期总结 课程设计小组 -迦瓦栈队 团队博客 读书笔记汇总 第一周 第二周 第三周 第四周 第五周 第六周 第七周 第八周 第九周 第十周 实验报告汇总 实验一 实验 ...

  9. 使用 HTML5 canvas 绘制精美的图形

    HTML5 是一个新兴标准,它正在以越来越快的速度替代久经考验的 HTML4.HTML5 是一个 W3C “工作草案” — 意味着它仍然处于开发阶段 — 它包含丰富的元素和属性,它们都支持现行的 HT ...

  10. linux系统设置静态IP 查看网卡配置文件

    http://jingyan.baidu.com/article/455a99508be7cda167277865.html vi /etc/sysconfig/network-scripts/ifc ...