简体   繁体   English

如何在Android中实现滑动并保持手势?

[英]How to implement swipe and hold gesture in Android?

I am trying to implement a "swipe and hold" gesture in Android where the user swipes from a point on the left to another point on the right, then continues to hold at the right point until a server-side action is complete. 我正在尝试在Android中实现“滑动并按住”手势,其中用户从左侧的一个点向右侧的另一个点滑动,然后继续保持在正确的点,直到服务器端操作完成。 The idea being that if the user lets go of the hold, the server-side action will be cancelled. 这样的想法是,如果用户放弃保留,则服务器端操作将被取消。

I've been trying to go about this the following way but have encountered an issue when getting to the hold part of the gesture. 我一直试图按照以下方式进行操作,但是在进入手势的保持部分时遇到了一个问题。 What I'd like to have happen is that when the user reaches point B on the right, the ACTION_MOVE is somehow converted into an ACTION DOWN for the view on the right and from then on, as long as the event ACTION_DOWN continues the gesture is valid, but if the user lets go or leaves the view area, it is invalid. 我想发生的事情是,当用户到达右侧的B点时,只要事件ACTION_DOWN继续,手势就会以某种方式将ACTION_MOVE转换为右侧视图的ACTION DOWN。有效,但如果用户放开或离开视图区域,则无效。 So the question is, is it possible to chain the ACTION_MOVE from left to right into a "hold" gesture once the user reaches point B on the right? 因此,问题是,一旦用户到达右侧的B点,是否可以将ACTION_MOVE从左到右链接为“保持”手势? I've tried adding an onTouch to point B after the swipe, but the only way that works is if the user lets go of the swipe, then presses point B again. 我尝试在滑动后将onTouch添加到B点,但是唯一可行的方法是,如果用户放开滑动,然后再次按下B点。 Will this be possible, or should I go about this a different way, such as drag and drop? 这是可能的,还是我应该以其他方式(例如拖放)进行操作?

Point A and B as found below are currently image views, but that's more placeholder than anything. 如下所示,点A和点B当前是图像视图,但是占位符比任何东西都要多。

private boolean mValidGesture = false;
Rect outRect = new Rect();
int[] location = new int[2];
private boolean isViewInBounds(View view, int x, int y){
    view.getDrawingRect(outRect);
    view.getLocationOnScreen(location);
    outRect.offset(location[0], location[1]);
    return outRect.contains(x, y);
}

...

    mPointA.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int x = (int)event.getRawX();
            int y = (int)event.getRawY();
            if(event.getAction() == MotionEvent.ACTION_MOVE){
                if (isViewInBounds(mPointB, x, y)) {
                    mPointB.dispatchTouchEvent(event);
                    Log.d(TAG, "onTouch ViewB");
                    Toast.makeText(MainActivity.this, "Swipe complete", Toast.LENGTH_SHORT).show();

                    //This is the part that happens only after you let go of the swipe :( 
                    mPointB.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            switch(event.getAction()) {
                                case MotionEvent.ACTION_DOWN:
                                    mValidGesture = true;
                                    Log.d(TAG, "Gesture: " + String.valueOf(mValidGesture));
                                    return true;
                                case MotionEvent.ACTION_UP:
                                    mValidGesture = false;
                                    Log.d(TAG, "Gesture: " + String.valueOf(mValidGesture));
                                    return true;
                            }
                            return false;
                        }
                    });
                } else if(isViewInBounds(mPointA, x, y)){
                    Log.d(TAG, "onTouch ViewA");
                }
            }
            // Further touch is not handled
            return false;
        }
    });

You don't need to put touchListener on pointB. 您无需将touchListener放在pointB上。 Try something like this: 尝试这样的事情:

 boolean serverActionStarted = false;

 @Override
 public boolean onTouch(View v, MotionEvent event) {
    int x = (int)event.getRawX();
    int y = (int)event.getRawY();
    if(event.getAction() == MotionEvent.ACTION_MOVE){

            if (isViewInBounds(mPointB, x, y)) {
                // TODO : swipe completed. Start server action
                serverActionStarted=true;
            }
   }else if(event.getAction() == MotionEvent.ACTION_UP && serverActionStarted){
       // TODO : cancel the server action
       serverActionStarted = false;
   }

So basically, when the user swipes from pointA to pointB, you start the server action and set a boolean serverActionStarted to true. 因此,基本上,当用户从pointA滑动到pointB时,您将启动服务器操作并将boolean serverActionStarted设置为true。 After that, if ACTION_UP event occurs, with the severAction having started, you cancel the server action. 此后,如果ACTION_UP事件发生,并且severAction已启动,则取消服务器操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM