在Android 6.0中,scaleGestureDetector.getScaleFactor()始终返回1.0 [英] scaleGestureDetector.getScaleFactor() always returning 1.0 in Android 6.0

查看:338
本文介绍了在Android 6.0中,scaleGestureDetector.getScaleFactor()始终返回1.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ScaleGestureDetector来检测捏和捏动作, 通过获取比例因子an(如果小于等于1)则缩小图像,反之亦然.

I am using ScaleGestureDetector to detect pinch out and pinch in actions, by getting the scale factor an if it is less then one then it is zoom out and vise versa.

但是问题是,在Android 6.0上,比例因子始终为1.0,这使得无法区分是捏还是捏.

But the problem is that on Android 6.0 the scale factor is always 1.0 which make it impossible to distinguish pinch in from pinch out.

在此先感谢您的帮助.

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MotionEventCompat;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.VelocityTracker;
import android.widget.FrameLayout;

public class TouchableWrapper extends FrameLayout
{
    private GestureDetectorCompat mGestureDetector;
    private ScaleGestureDetector mScaleGestureDetector;
    private VelocityTracker mVelocityTracker;
    private boolean acceptEvents=true;
    ScaleGestureDetector temp;


private final GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener()
{

    @Override
    public boolean onDoubleTap(MotionEvent e)
    {
        EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.MAP_DOUBLE_TOUCHED));
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        return super.onDoubleTapEvent(e);
    }



};

private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener = new ScaleGestureDetector.SimpleOnScaleGestureListener()
{
    /**
     * This is the active focal point in terms of the viewport. Could be a local
     * variable but kept here to minimize per-frame allocations.
     */

    float startingSpan;
    float startFocusX;
    float startFocusY;

    @Override
    public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector)
    {

        temp=scaleGestureDetector;
        startingSpan = scaleGestureDetector.getCurrentSpan();
        startFocusX = scaleGestureDetector.getFocusX();
        startFocusY = scaleGestureDetector.getFocusY();

        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetector scaleGestureDetector)
    {
        super.onScale(scaleGestureDetector);

        float scale = scaleGestureDetector.getScaleFactor();
        //mVelocityTracker.computeCurrentVelocity(1000);



        if(acceptEvents)
        {

            Log.e("scaleGestureDetector.getCurrentSpan()", scaleGestureDetector.getCurrentSpan()+"");
            Log.e("startingSpan", startingSpan+"");
            Log.e("onScale",scale+"");

            if (scale <= 1.0)
            {
                acceptEvents = false;
                EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.MAP_ZOOMED_OUT));
            }
            else
            {
                acceptEvents = false;
                EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.MAP_ZOOMED_IN));
            }
        }

        return true;
    }
};

public TouchableWrapper(Context context)
{
    super(context);
    mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener);
    mGestureDetector = new GestureDetectorCompat(context, mGestureListener);
    mVelocityTracker = VelocityTracker.obtain();
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
    mGestureDetector.onTouchEvent(ev);
    //Log.e("Motion Event pointer count",ev.getPointerCount()+"");


    int action = MotionEventCompat.getActionMasked(ev);

    switch (action)
    {
        case (MotionEvent.ACTION_DOWN):
            Log.e("MotionEvent", "Action was DOWN");
            break;
        case (MotionEvent.ACTION_MOVE):
            //Log.e("MotionEvent", "Action was MOVE");
            /*if(acceptEvents)
            {
                if(MotionEventCompat.getPointerCount(ev)==2)
                {

                    x1=MotionEventCompat.getX(ev,0);
                    x2=MotionEventCompat.getX(ev,1);
                    y1=MotionEventCompat.getY(ev,0);
                    y2=MotionEventCompat.getY(ev,1);


                    if(differenceX==0||differenceY==0)
                    {
                        differenceX=Math.abs(x1-x2);
                        differenceY=Math.abs(y1-y2);
                    }
                    else
                    {
                        differenceXPrime=Math.abs(x1-x2);
                        differenceYPrime=Math.abs(y1-y2);


                        if (differenceXPrime-differenceX>100 || differenceYPrime-differenceY>100)
                        {
                            Log.e("Zoomed out","differenceX:"+differenceX+"         differenceXPrime:"+differenceXPrime+"           differenceY:"+differenceY+"            differenceYPrime:"+differenceYPrime);
                            differenceX=0;
                            differenceY=0;
                            acceptEvents=false;
                            EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.MAP_ZOOMED_IN));

                        }
                        else if(differenceX-differenceXPrime>100 || differenceY-differenceYPrime>100)
                        {
                            Log.e("Zoomed in","differenceX:"+differenceX+"         differenceXPrime:"+differenceXPrime+"           differenceY:"+differenceY+"            differenceYPrime:"+differenceYPrime);
                            differenceX=0;
                            differenceY=0;
                            acceptEvents=false;
                            EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.MAP_ZOOMED_OUT));
                        }
                    }
                }
            }*/

            break;
        case (MotionEvent.ACTION_UP):
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.ENABLE_MAP_GESTURE));
                    acceptEvents=true;
                }
            },300);

            Log.e("MotionEvent", "Action was UP");
            break;
        case (MotionEvent.ACTION_POINTER_UP):
            Log.e("MotionEvent", "Action was POINTER UP");
            break;
        case (MotionEvent.ACTION_POINTER_DOWN):
            EventBus_Singleton.getInstance().post(new EventBus_Poster(Constants.DISABLE_MAP_GESTURE));
            Log.e("MotionEvent", "Action was POINTER DOWN");
            break;
        case (MotionEvent.ACTION_CANCEL):
            Log.e("MotionEvent", "Action was CANCEL");
            break;
        case (MotionEvent.ACTION_OUTSIDE):
            Log.e("MotionEvent", "Movement occurred outside bounds of current screen element");
            break;
    }
    mVelocityTracker.addMovement(ev);
    mScaleGestureDetector.onTouchEvent(ev);
    return super.onInterceptTouchEvent(ev);
}

}

推荐答案

我认为问题在于,当您缓慢地执行捏手势时,此类会丢弃手指之间较小的跨度增量.它只担心跨度的大差异.

I think the problem is that when you do the pinch gesture slowly, this class discards the small increments of span between the fingers. It only worries about large differences in span.

如果慢慢捏,它将记录许多不同的触摸移动事件,每个事件的跨度(手指之间)仅与上一个事件稍有不同.它认为跨度没有变化,因此比例因子为1.

If you pinch slowly it will register a number of different touch moving events, each one with a span (between the fingers) only slightly different than the previous event. It considers the span didn't change thus the scale factor is 1.

如果您捏紧一点,它将记录比上一个事件更大的跨度,并为您提供一个不同于1的因数.

If you pinch fast, it will register a larger span than the last event and will give you a factor different than 1.

在我的解决方案中,我自定义类.我自己计算比例因子.只要不捏,比例因子就是1.然后,当您开始捏捏时,缩放因子是根据捏捏手势的开始而计算的,而上一个触摸事件是不是的.

In my solution I customize the class. I calculate the scale factor myself. The scale factor is 1 as long as you're not pinching. Then when you start pinching the scale factor is calculated from the beginning of the pinch gesture and not from the previous touch event.

因此,我将创建ScaleGestureDetector的子类,并在其中重写onTouchEvent().在其中,我跟踪两只手指,如果两只手指都在移动,则测量并保持开始跨度.我覆盖getScaleFactor(),并且该系数是根据当前跨度与起始跨度进行计算的.当任何一根手指移开时,缩放就完成了.该系数回到1.

So I make a subclass of ScaleGestureDetector and in it I override onTouchEvent(). In it I keep track of both fingers, and if both are moving I measure the start span and keep it. I override getScaleFactor() and the factor is calculated based on the current span versus the start span. When any of the fingers is removed, the scaling is finished; the factor goes back to 1.

这篇关于在Android 6.0中,scaleGestureDetector.getScaleFactor()始终返回1.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆