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中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤