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实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到