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. [转载]java中try 与catch的使用

    留着以后看 原文地址:与catch的使用">java中try 与catch的使用作者:碌碌如玉 try{ //代码区 }catch(Exception e){ //异常处理 } 代码区 ...

  2. LinuxShell脚本攻略--第一章 小试牛刀

    使用 shell 进行数学运算: #!/bin/bash no1=; no2=; let result=no1+no2 echo $result result=$[ $no1 + no2 ] resu ...

  3. Python语言及其应用 - 知识点遍历

    遍历python语法     2.基本元素:数字.字符串和变量 2.1 python有哪些基本类型? 布尔型(True, False),整型(42,100000),浮点型(3.14159,1.0e8) ...

  4. android UI库

    https://github.com/wasabeef/awesome-android-ui List of Android UI/UX Libraries A curated list of awe ...

  5. 使用PowerShell简化我的工作

    欢迎关注我的社交账号: 博客园地址: http://www.cnblogs.com/jiangxinnju/p/4781259.html GitHub地址: https://github.com/ji ...

  6. Ubuntu下解决bash 没有那个文件或目录的方法

    因为之前电脑硬盘坏掉,维修换了新硬盘,今天重新安装了ubuntu,装好之后就赶紧搭建工作环境,将备份的资料拷贝进来,搭建交叉编译环境,但是发现,修改bashrc中PATH绝对路径指向交叉编译器后,在命 ...

  7. linux服务器挂载第二块磁盘图文解说

    文章来源:http://www.cndns.com/help/help_con.aspx?hid=394 Linux磁盘挂载是比较常见的管理操作之一.我司橙云预装的linux系统有2块盘,一块为系统盘 ...

  8. 用excel处理重复数据

    我们在处理数据时,重复数据常常会对分析造成很大麻烦,因此数据整理初期一个重要的工作是排重,excel2007以上版本中有一个删除重复项功常便捷,但是每次点来点去也很麻烦,下面我们用公式来对一些重复数据 ...

  9. [转载]SoapUI 参数化&数据库连接

    引用自 : http://www.cnblogs.com/liulinghua90/p/4954045.html 如果是没有代码能力的小白,要利用工具进行接口测试的时候,经常会遇到接口地址 或者接口参 ...

  10. linux安装.run

    chmod +x ./framework-3.6.0-linux-full.runsudo ./framework-3.6.0-linux-full.run