美文网首页
Android 放大缩小容器-ScalableViewConta

Android 放大缩小容器-ScalableViewConta

作者: 程序猿小钟 | 来源:发表于2021-01-15 17:12 被阅读0次

前言

作为一个Android开发,当系统控件满足不了业务需求的时候,就需要程序猿自己自定义控件或者容器。所以自定义控件、自定义容器,是我们必须掌握的技术。本次,程序猿小钟就为大家介绍一下自定义的放大缩小容器,并粗略的介绍一下容器中用到的GestureDetector和ScaleGestureDetector,如果大家想要更加深入了解这两个类的话,可以自己阅读一下源码。

手势工具类GestureDetector

GestureDetector类主要是用于识别一些特定的动作手势,例如单击、双击、长按等。只需要在容器中初始化并且在onTouchEvent事件中调用GestureDetector.onTouchEvent(motionEvent),并通过GestureDetector中的接口SimpleOnGestureListener监听到各种手势的回调。

SimpleOnGestureListener是GestureDetector的内部类,主要的方法有:

缩放手势工具类ScaleGestureDetector

ScaleGestureDetector类主要是用于识别缩放手势的工具。使用方式也是只需要在容器初始化并且在onTouchEvent事件中调用ScaleGestureDetector.onTouchEvent(motionEvent),并通过ScaleGestureDetector中的接口SimpleOnScaleGestureListener监听到缩放手势的回调。

SimpleOnScaleGestureListener是ScaleGestureDetector的内部类,方法有【监听缩放手势开始回调】、【监听缩放手势回调】、【监听缩放手势结束回调】:

放大缩小容器ScalableViewContainer

/**

* 放大缩小容器(Android7以上适用)

*/

public class ScalableViewContainer extends FrameLayout {

    //常量定义

    private final float MIN_SCALE =1.0f;

    private final float MID_SCALE =1.75f;

    private final float MAX_SCALE =3.0f;

    //手势

    private GestureDetector gestureDetector;

    //缩放手势

    private ScaleGestureDetector scaleDetector;

    private int width; // 原始宽度

    private int height; // 原始高度

    private float curScale =1.0f; // 当前缩放比例

    private float translateX; // 当前X偏移

    private float translateY; // 当前Y偏移

    private float minTransX; // 最小X偏移

    private float maxTransX; // 最大X偏移

    private float minTransY; // 最小Y偏移

    private float maxTransY; // 最大Y偏移

    public ScalableViewContainer(@NonNull Context context) {

        this(context, null);

    }

    public ScalableViewContainer(@NonNull Context context, @Nullable AttributeSet attrs) {

        this(context, attrs, 0);

    }

    public ScalableViewContainer(@NonNull Context context, @Nullable AttributeSet attrs, int         defStyleAttr) {

        super(context, attrs, defStyleAttr);

        //初始化手势工具类,自定义监听

        gestureDetector =new GestureDetector(context, new CustomOnGestureListener());

        scaleDetector =new ScaleGestureDetector(context, new                 CustomOnScaleGestureListener());

    }

    /**

    * 重置

    */

    public void resetScale() {

        setScale(0);

    }

    @Override

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        super.onSizeChanged(w, h, oldw, oldh);

        width = w;

        height = h;

    }

    /**

    * 触摸事件

    */

    @Override

    public boolean onTouchEvent(MotionEvent ev) {

        scaleDetector.onTouchEvent(ev);

        gestureDetector.onTouchEvent(ev);

        return true;

    }

    /**

    *  设置缩放

    */

    private void setScale(float scale) {

        float oldScale =curScale;

       if (scale <  MIN_SCALE) {

            curScale =MIN_SCALE;

        }else if (scale >MAX_SCALE) {

            curScale =MAX_SCALE;

        }else {

            curScale = scale;

        }

        if (oldScale !=curScale) {

            getChild().setScaleX(curScale);

            getChild().setScaleY(curScale);

            updateTrans();

        }

}

    /**

    *  缩放后调整偏移

    */

    private void updateTrans() {

        minTransX = -width * (curScale -1) /2;

        maxTransX =width * (curScale -1) /2;

        minTransY = -height * (curScale -1) /2;

        maxTransY =height * (curScale -1) /2;

        setTrans(translateX, translateY);

    }

    /**

    * 避免缩放时出现黑边

    */

    private void setTrans(float transX, float transY) {

           if (transX < minTransX) {

                translateX =minTransX;

           }else if (transX >maxTransX) {

                translateX =maxTransX;

            }else {

                translateX = transX;

            }

             if (transY < minTransY) {

                translateY =minTransY;

             }else if (transY >maxTransY) {

                translateY =maxTransY;

             }else {

                translateY = transY;

              }

            getChild().setTranslationX(translateX);

            getChild().setTranslationY(translateY);

    }

    /**

    * 获取容器中首个控件

    */

    private View getChild() {

            return getChildAt(0);

    }

    /**

    * 缩放手势监听

    */

    private class CustomOnScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        @Override

        public boolean onScale(ScaleGestureDetector detector) {

               if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

                    float tempScale =curScale * detector.getScaleFactor();

                    setScale(tempScale);

                    return true;

                }else{

                    return false;

                }

    }

}

    /**

    * 手势监听

    */

    private class CustomOnGestureListener extends GestureDetector.SimpleOnGestureListener {

        /**

        * 用户按下触摸屏,并拖动

        */

        @Override

        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

                    float transX =translateX -= distanceX;

                    float transY =translateY -= distanceY;

                    setTrans(transX, transY);

                    return true;

            }else{

                    return false;

            }

    }

        /**

        *  用户双击屏幕

        */

        @Override

        public boolean onDoubleTap(MotionEvent e) {

           //因Android7以下的手机缩放方法异常,把缩放功能控制在Android7以上的手机才能使用

            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

                float tempScale;

                if (curScale >=MIN_SCALE && curScale < MID_SCALE){

                    tempScale =MID_SCALE;

                }else if (curScale >=MID_SCALE && curScale < MAX_SCALE){

                    tempScale =MAX_SCALE;

                }else {

                    tempScale =MIN_SCALE;

                }

                    setScale(tempScale);

                    return true;

                }else{

                    return false;

                }

        }

    }

}

使用方式

                                        2021年1月15日程序猿小钟带着ScalableViewContainer到此一游~

相关文章

  • Android 放大缩小容器-ScalableViewConta

    前言 作为一个Android开发,当系统控件满足不了业务需求的时候,就需要程序猿自己自定义控件或者容器。所以自定义...

  • 转场动画(三) --交互式转场缩小动画

    一 捏合放大的图片自动缩小隐藏 在点击放大的视图容器中有scrollView 可以缩放 在scrollView的...

  • android 评论框 缩小/放大

    知识点学习地址 https://blog.csdn.net/ringopaul/article/details/5...

  • Android 放大缩小图片查看

    点击查看图片,可放大缩小,再次点击时关闭。 先上效果图,没图说个cz!!! 实现方法: 1.添加依赖 在build...

  • 222天--放大和缩小2022-08-21

    222天--放大和缩小2022-08-21 ?放大与缩小? 把困难放大,恩典缩小,你就是一个痛苦的人。 把恩典放大...

  • 20161216 Day11/35 爱丽丝群04-梦在云端【专注

    任务一: 用时 : 1"15.54' 任务二: 1.我用手机看,用手指将图片放大缩小、放大缩小、放大缩小……这样这...

  • 放大 缩小

    每个人都跟宇宙一样,自我膨胀着,我也不例外。所以我们总感觉我们做的很多,做的很好,但其实是我们用放大镜看我们的成果...

  • 放大缩小

    心情不好的时候,就喜欢往人多的地方去。拥挤的公交,拥挤的地铁,拥挤的商圈,嘈杂的人声。人来人往,车去车来。忽而,自...

  • 缩小,放大

    想象在你心中有一个很小的光球,像一个芥末子那么大。 现在放大去看,看着很近很近,他对你来说就像一个房间那么大。 这...

  • 放大?缩小?

    昨天跟一个朋友约了饭,她最近不太好。人在经历很多事,尤其是当生活充斥着无力感的时候,总会觉得既然努力与否,结果都一...

网友评论

      本文标题:Android 放大缩小容器-ScalableViewConta

      本文链接:https://www.haomeiwen.com/subject/iyswaktx.html