android 自定義控件實現圖片縮放

2024-02-16 05:18

本文主要是介绍android 自定義控件實現圖片縮放,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

public class MyImageView extends ImageView implements View.OnTouchListener
{

        public interface ImageViewVisiable
        {

              // 其他控件隱藏域顯示囘調函數
                public void visiable(int flag);
        }
        
        private ImageViewVisiable mImageViewVisiable;
        
        public void setImageViewVisiable(ImageViewVisiable imageViewVisiable)
        {
                 this.mImageViewVisiable = imageViewVisiable;
        }
        
        /**
         * 变换图片的矩阵
         */
        private Matrix matrix;

        /**
         * 记录图片矩阵状态
         */
        private Matrix saveMatrix;

        /**
         * 起始触摸点
         */
        private PointF start;

        /**
         * 触摸状态
         */
        public int MODE = MODE_INIT;

        /**
         * 初始状态,点击后隐藏标题、评论等
         */
        public static final int MODE_INIT = 1;

        /**
         * 图片为初始大小的满屏状态,未缩放,点击后显现标题、评论等
         */
        public static final int MODE_FULLSCREEN = 2;

        /**
         * 缩放状态
         */
        public static final int MODE_ZOOM = 3;

        /**
         * 拖拽状态
         */
        public static final int MODE_DRAG = 4;

        private float oldDistance;

        private float newDistance;

        private PointF midPoint;

        /**
         * 这一次手指移动后产生的缩放比例,初始是1
         */
        private float scale = 1;

        /**
         * 之前保存的缩放比例,初始是1
         */
        private float savedScale = 1;

        /**
         * 组件
         */
        
        private int mWidth;
        
        private int mHeight;
        
        private Context context;
        
        float left;
        float top;
        float right;
        float bottom;
        
        /** <默认构造函数>
         */
        public MyImageView(Context context) {
                super(context);
                init(context);
        }
        
        /** <默认构造函数>
         */
        public MyImageView(Context context,AttributeSet attrs) {
                super(context,attrs);
                init(context);
        }
        
        private void init(Context context)
        {
                this.mWidth = 400;
                this.mHeight = 400;
                this.context = context;
                matrix = new Matrix();
                saveMatrix = new Matrix();
                start = new PointF();
                midPoint = new PointF();
                setOnTouchListener(this);
        }

        private boolean getImageInfo(ImageView view)
    {
        Drawable mDrawable = null;
        if (view != null)
        {
           mDrawable =  view.getDrawable();
           if (mDrawable != null)
           {
               Rect rect = mDrawable.getBounds(); 
               float[] values = new float[9]; 
               matrix.getValues(values); 
                left = values[2];
               top = values[5];
               right = left + rect.width() * values[0];
               bottom = top + rect.height() * values[0];
           }
        }
        if (mDrawable == null)
        {
                LogUtil.d("獲取圖片失敗,請檢查是否因為內存吃緊,圖片被回收");
            return false;
        }
        return true;
    }
        
        
        public void postTranslate(MotionEvent event, ImageView view)
    {
        getImageInfo(view);
        LogUtil.d("Move获取当前图片的left:" + left + "|top:" +top + "|right:" + right + "|bottom:" + bottom);
        matrix.set(saveMatrix);

        float translateX = (event.getX() - start.x);
        float translateY = (event.getY() - start.y);
        LogUtil.d("把图片平移至:" + translateX + "x" + translateY);
        matrix.postTranslate(translateX,translateY);
    }
        
        public void stopOutScreen()
    {
        float translateX = 0;
        float translateY = 0;
        if (right > mWidth && left < 0)
        {
        }
        else
        {
            //往左
            if (right < mWidth) //当图片宽度已经大于屏幕
            {
                translateX = mWidth - right  ;
            }
            else if (left > 0)
            {
                translateX =0 - left;
            }

        }
        if (top < 0 && bottom > mHeight)
        {
        }
        else
        {
          //往上滑动
            if (top <0)
            {
                translateY =  0 - top;
            }
            else if (bottom > mHeight)
            {
                translateY = mHeight -bottom;
            }
        }
        LogUtil.d("图片还原至:" + translateX + "x" + translateY);
        matrix.postTranslate(translateX,translateY);
    }
        
        public void setPoint(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);

        }
        
        /**
         * 获取2个触控点距离
         * 
         * @param event
         * @return
         */
        public float caculateDistance(MotionEvent event)
        {
                float x = 0;
                float y = 0;
                try{
                        x = event.getX(0) - event.getX(1);
                        y = event.getY(0) - event.getY(1);
                }catch(IllegalArgumentException e){
                }
                return FloatMath.sqrt(x * x + y * y);
        }

        public void actionDown(ImageView v, MotionEvent event)
        {
                LogUtil.d("ACTION_DOWN  " + MODE);
                matrix.set(v.getImageMatrix());
                saveMatrix.set(matrix);
                // 得到当前点的位置
                start.set(event.getX(), event.getY());
                // 拖动
                if (savedScale > 1)
                {
                        MODE = MODE_DRAG;
                }
                getImageInfo(v);
                v.setImageMatrix(matrix);
        }
        
        public void actionMove(ImageView v, MotionEvent event)
        {
                // 拖动
                if (MODE == MODE_DRAG) {
                        postTranslate(event, v);
                }
                // 缩放
                else if (MODE == MODE_ZOOM) {

                        newDistance = caculateDistance(event);
                        if (newDistance > 5f) {
                                matrix.set(saveMatrix);
                                scale = newDistance / oldDistance;
                                matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                        }
                }
                v.setImageMatrix(matrix);
        }
        
        public void actionPointerDown(ImageView v, MotionEvent event)
        {
                LogUtil.d("ACTION_POINTER_DOWN  " + MODE);
                if (MODE == MODE_FULLSCREEN || MODE == MODE_DRAG)
                {
                        oldDistance = caculateDistance(event);
                        v.setScaleType(ScaleType.MATRIX);
                        if (oldDistance > 10f)
                        {
                                saveMatrix.set(matrix);
                                setPoint(midPoint, event);
                                MODE = MODE_ZOOM;
                        }
                }
                v.setImageMatrix(matrix);
        }
        
        public void actionPointerUp(ImageView v, MotionEvent event)
        {
                LogUtil.d("ACTION_POINTER_UP  " + MODE);
        }
        
        
        public void actionUp(MotionEvent enent)
        {
                LogUtil.d("ACTION_UP  " + MODE);
                // 隐藏标题、评论
                if (MODE == MODE_INIT)
                {
                        MODE = MODE_FULLSCREEN;
                         mImageViewVisiable.visiable(GONE);
                }
                // 显示标题、评论
                else if (MODE == MODE_FULLSCREEN)
                {
                        mImageViewVisiable.visiable(VISIBLE);
                        MODE = MODE_INIT;
                }
                // 缩放
                else if (MODE == MODE_ZOOM)
                {
                        savedScale *= scale;
                        if (savedScale > 2)
                        {
                                setScaleType(ScaleType.FIT_CENTER);
                                savedScale = 1;
                                scale = 1;
                                MODE = MODE_FULLSCREEN;
                        } else if (savedScale < 1)
                        {
                                setScaleType(ScaleType.FIT_CENTER);
                                savedScale = 1;
                                scale = 1;
                                MODE = MODE_FULLSCREEN;
                        } else if (savedScale == 1)
                        {
                                MODE = MODE_FULLSCREEN;
                        }
                        
                }
                else if (MODE == MODE_DRAG)
                {
                    stopOutScreen();
                }
                setImageMatrix(matrix);
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) 
        {
                ImageView view = (ImageView) v;
                switch (event.getAction() & MotionEvent.ACTION_MASK)
                {
                case MotionEvent.ACTION_DOWN:
                        
                        actionDown(view, event);
                        break;
                case MotionEvent.ACTION_MOVE:
                        
                        actionMove(view, event);
                        break;
                case MotionEvent.ACTION_POINTER_DOWN:
                        
                        actionPointerDown(view, event);
                        break;
                case MotionEvent.ACTION_POINTER_UP:
                        
                        actionPointerUp(view, event);
                        break;
                case MotionEvent.ACTION_UP:
                        
                        actionUp(event);
                        break;
                }
                return true;
        }
        
}

这篇关于android 自定義控件實現圖片縮放的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/713595

相关文章

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

Android实现悬浮按钮功能

《Android实现悬浮按钮功能》在很多场景中,我们希望在应用或系统任意界面上都能看到一个小的“悬浮按钮”(FloatingButton),用来快速启动工具、展示未读信息或快捷操作,所以本文给大家介绍... 目录一、项目概述二、相关技术知识三、实现思路四、整合代码4.1 Java 代码(MainActivi

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me