【问题标题】:How to see if a user is pressing on same location on screen for 2 seconds?如何查看用户是否在屏幕上的同一位置按下 2 秒?
【发布时间】:2017-02-14 18:59:06
【问题描述】:

我有一个简单的自定义视图,其中包含 onDraw 和 onTouchEvent 方法。我需要以某种方式检查用户是否将手指放在同一位置(Y 坐标)超过 2 秒。

编辑:添加了描述和代码。

我的简单自定义视图正在做的是在用户手指下方绘制一条水平线。当您在屏幕上上下移动时,水平线会跟随您。 如果用户在同一位置按住手指 2 秒,我要做的是升起一个标志(布尔值) - 换句话说,如果这条线围绕某个 Y 坐标2 秒。

public class RateView extends View {

float touchY = (getHeight() / 2);
boolean isPressed = false;
Paint paint = new Paint();

//Bunch of standard constructors

private void init(Context context, AttributeSet attr) {
    paint.setColor(ContextCompat.getColor(context, R.color.line));
    paint.setStrokeWidth(10);
    paint.setAntiAlias(true);
}

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    //If pressed -> draw horizontal line
    if (isPressed) {
        canvas.drawLine(0, touchY, (canvas.getWidth()), touchY, paint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent motionEvent) {

    switch (motionEvent.getAction()) {
        case MotionEvent.ACTION_DOWN:
            isPressed = true;

            break;
        case MotionEvent.ACTION_MOVE:
            touchY = motionEvent.getY();

            break;
        case MotionEvent.ACTION_UP:
            isPressed = false;

            break;
    }
    invalidate();
    return true;
}}

【问题讨论】:

    标签: android location ondraw seconds ontouch


    【解决方案1】:

    您可以将 runnable 与 runnable 结合使用来实现此目的。您可以运行一个 Runnable,它仅在仍然按下视图并且执行期间的 y 坐标在第一次启动 runnable 时的 y 坐标范围内时在两秒钟后执行您想要的内容。代码将如下所示。

    boolean mViewIsPressed = false;
    float yCoordPrev;
    float yCoordCurr;
    Runnable runnable;
    
    @Override
    public boolean onTouchEvent(final MotionEvent event) {
        // MotionEvent object holds X-Y values
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            String text = "You click at x = " + event.getX() + " and y = " + event.getY();
            Log.d("debug-x: ", String.valueOf(event.getX()));
            Log.d("debug-y: ", String.valueOf(event.getY()));
            Toast.makeText(this, text, Toast.LENGTH_LONG).show();
            yCoordPrev = event.getY();
    
            runnable = new Runnable() {
                public void run() {
    
    
                    //Check if user is still holding down on the view
                    if (mViewIsPressed) {
                        yCoordCurr = event.getY();
    
                        //Check if position that is being held down is the same (or within range) as 2 seconds ago
                        if ((yCoordCurr < yCoordPrev+10) && (yCoordCurr > yCoordPrev -10) ){
                            //Do what you want here after 2 seconds of pressing
                            Log.d("debugFireEvent: ", "fire");
                        }
                    }
                }
            };
    
            handler.postDelayed(runnable, 2000);
            mViewIsPressed = true;
    
    
        }
        if(event.getAction() == MotionEvent.ACTION_UP) {
            if(mViewIsPressed) {
                mViewIsPressed = false;
                yCoordCurr = event.getY();
                //Cancel the runnable because the user stopped pressing
                handler.removeCallbacks(runnable);
                }
            }
        return super.onTouchEvent(event);
    }
    

    您可以在 runnable 中使用 if 语句中的范围,更准确地说是 if ((yCoordCurr &lt; yCoordPrev+10) &amp;&amp; (yCoordCurr &gt; yCoordPrev -10) ),但由于即使用户仍在同一位置按下手指也会移动一点,我认为最好有一个范围。

    【讨论】:

    • 哇,我想这正是我想要的。只需要一个小小的调整。稍微描述一下我的视图在做什么:使用我的 onDraw 方法,我在用户手指下方绘制一条水平线,以便他可以上下移动它,并且由于 ACTION_MOVE 捕获坐标并发送到绘图,这条线也会移动。我想要实现的是,如果用户将线围绕某个 Y 坐标保持 2 秒,则会弹出图像。如果我把你的代码放在 ACTION_MOVE 中,它会这样工作吗?
    • 我认为您可以应用相同的逻辑,除非您必须跟踪用户是否向上移动了手。如果您可以在问题中提供更多代码,那将会更有帮助和清晰。您可以尝试使用此逻辑,看看这是否适合您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    相关资源
    最近更新 更多