ScaleGestureDetector
  JKAkDL5PppSO 2023年11月02日 118 0


// 用于处理缩放的工具类,用法与GestureDetector类似,都是通过onTouchEvent关联相应的MotionEvent。
// 使用该类时,用户需要拆入一个完整的连续不断的motion事件(包含ACTION_DOWN,ACTION_MOVE和ACTION_UP事件)
final ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(this,
        new ScaleGestureDetector.OnScaleGestureListener() {
            // 缩放时。返回值代表本次缩放事件是否已被处理。如果已被处理,那么detector就会
            // 重置缩放事件;如果未被处理,detector会计算进行计算,修改getScaleFactor()的返回
            // 值,知道被处理为止。因此,它常用在判断只有缩放值达到一定数值时才进行缩放。例如
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                Log.i(TAG, "onScale facotr = " +detector.getScaleFactor());
                //if(detector.getScaleFactor() < 2) {
                //    return false;
                //}
                // mMatrix.preScale(detector.getScaleFactor(), detector.getScaleFactor())
                // setImageMatrix(mMaxtrix)
                /**
                 * 可以看出getScaleFactor返回的值由小变大,直到大于2后又从1开始变大。这是因为
                 * 当缩放因子(getScaleFactor的返回值)小于2时,onScale返回的时false,此时
                 * detector认为本次缩放尚未结束,所以本次计算缩放因子时仍旧以上次结束时为准,
                 * 这样就导致了手指外移时搜房参数越来越大;当达到2后,本次缩放结束,再次获得缩放因子时
                 * 的基准就变成刚刚结束的为止了,因此,获取的缩放因子会猛然变小(因为手指外移,执行的是
                 * 放大操作,所以缩放因子会大于1)。
                 */
                return true;
            }
            // 缩放开始,该detector是否处理候后继的缩放事件。返回false时,不会执行onScale
            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                return false;
            }
            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
                // 缩放结束时
            }
        }
);
//获取本次缩放事件的缩放因子(缩放事件以onScale)返回值为基准,一旦该方法返回true,
//代表本次事件结束,要开启下次事件)。它的返回值时指本次事件中的缩放值,并不是相对于开始的值。
//如一张图片开始放大2倍,后来又放到1.1 倍。那么第二次放大时,该方法返回的就是1.1,
//而不是总放大倍数:2*1.1
scaleGestureDetector.getScaleFactor();
//返回手势过程中,组成该手势的两个触点的当前距离。返回值以像素为单位的触点距离。
scaleGestureDetector.getCurrentSpan();
//跟getCurrentSpan()类似,只不过一个是返回的是x轴上的距离,一个是y轴上的距离。
//注意:返回值有可能为负数。这两个方法的返回值和getCurrentSpan()的返回值满足勾股定理。
scaleGestureDetector.getCurrentSpanX();
scaleGestureDetector.getCurrentSpanY();
//返回组成该手势的两个触点的中点在组件上的y,x轴坐标,单位为像素。
scaleGestureDetector.getFocusX();
scaleGestureDetector.getFocusY();
//返回缩放过程中,组成当前缩放手势的两个触点的前一次距离。
//假设有a,b,c三个手指,某一次a,b组成缩放手势,两者的距离是300;随后一直是b,c组成缩放手势,当c抬起时,b,c的距离时100。
//此时,ab会组成缩放手势,该值返回的就是300,而不是b,c的100。
scaleGestureDetector.getPreviousSpan();
scaleGestureDetector.getPreviousSpanX();
scaleGestureDetector.getPreviousSpanY();
//获取当前motion事件的时间
//mCurrTime = event.getEventTime();//该方法返回的就是mCurrTime的
scaleGestureDetector.getEventTime();
//返回上次缩放事件结束时到当前的时间间隔
scaleGestureDetector.getTimeDelta();
//如果缩放手势正处在进行中,返回true;否则返回false。
scaleGestureDetector.isInProgress();
recyclerView.setOnTouchListener(new View.OnTouchListener() {
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        scaleGestureDetector.onTouchEvent(event);
        //gestureDetector.onTouchEvent(event);
        return true;
    }
});

实例

public class TestScaleActivity extends AppCompatActivity {

    private SurfaceView mSurfaceView;
    private ScaleGestureDetector mGestureDetector;
    private Bitmap bitmap;
    private SurfaceHolder mSurfaceHolder;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_scale);
        mSurfaceView = findViewById(R.id.mSurfaceView);
        mSurfaceHolder = mSurfaceView.getHolder();

        mGestureDetector = new ScaleGestureDetector(this, new MyScaleGestureListener());

        // 点击按钮
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
                //锁定整个SurfaceView
                Canvas mCanvas = mSurfaceHolder.lockCanvas();
                //画图
                mCanvas.drawBitmap(bitmap, 0f, 0f, null);
                //绘制完成,提交修改
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
                //重新锁定一次
                mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            }
        });


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }


    public class MyScaleGestureListener implements ScaleGestureDetector.OnScaleGestureListener {

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            Matrix matrix = new Matrix();
            //缩放比例
            float scale = detector.getScaleFactor() / 3;
            matrix.setScale(scale, scale);

            // 锁定整个Sureface
            Canvas mCanvas = mSurfaceHolder.lockCanvas();
            //清屏
            mCanvas.drawColor(Color.BLACK);
            //画缩放后的图
            mCanvas.drawBitmap(bitmap, matrix, null);
            // 绘制完成,提交修改
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            //重新锁一次
            mSurfaceHolder.lockCanvas(new Rect(0,0,0,0));
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            return false;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            // 一定要返回true才会进入onScale这个函数
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {

        }
    }

}


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  zRK4BzBUK860   2023年11月02日   82   0   0 配置文件服务器ide
  Fo7woytj0C0D   2023年12月23日   31   0   0 pythonsedidepythonidesed
JKAkDL5PppSO