考虑以下方案(为了更好地理解我的问题)。

如您所见,我正在考虑一个由填充包围的列表 View 。现在,如果用户按下一个列表 View 项,那么我提供的操作就是浅蓝色背景色。现在,我的应用程序正在处理onTouch事件本身,以确定诸如

  • 单击
  • 从左向右滑动
  • 从右向左滑动

  • 这是我的代码。
    public boolean onTouch(View v, MotionEvent event) {
            if(v == null)
            {
                mSwipeDetected = Action.None;
                return false;
            }
            switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN: {
                downX = event.getRawX();
                downY = event.getRawY();
                mSwipeDetected = Action.Start;
    
             // Find the child view that was touched (perform a hit test)
                Rect rect = new Rect();
                int childCount = listView.getChildCount();
                int[] listViewCoords = new int[2];
                listView.getLocationOnScreen(listViewCoords);
                int x = (int) event.getRawX() - listViewCoords[0];
                int y = (int) event.getRawY() - listViewCoords[1];
                View child;
                for (int i = 0; i < childCount; i++) {
                    child = listView.getChildAt(i);
                    child.getHitRect(rect);
                    if (rect.contains(x, y)) {
                        mDownView = child;
                        break;
                    }
                }
    
    
                return false; // allow other events like Click to be processed
            }
            case MotionEvent.ACTION_MOVE: {
                upX = event.getRawX();
                upY = event.getRawY();
                float deltaX=0,deltaY=0;
                 deltaX = downX - upX;
                 deltaY = downY - upY;
    
                    if(deltaY < VERTICAL_MIN_DISTANCE)
                    {
                                setTranslationX(mDownView, -(deltaX));
                                setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / listView.getWidth())));
                                return false;
                    }
                    else
                    {
                        forceBringBack(v);
                    }
    
                              return false;
    
            }
            case MotionEvent.ACTION_UP:
            {
    
                 stopX = event.getX();
                 float stopValueY = event.getRawY() - downY;
                 float stopValue = stopX - downX;
    
                 if(!mDownView.isPressed())
                 {
                     forceBringBack(mDownView);
                     return false;
                 }
    
                 boolean dismiss = false;
                 boolean dismissRight = false;
    
    
                 if(Math.abs(stopValue)<10)
                 {
                     mSwipeDetected = Action.Start;
                 }
                 else
                 {
                     mSwipeDetected = Action.None;
    
                 }
                 String log = "";
                 Log.d(log, "Here is Y" + Math.abs(stopValueY));
                 Log.d(log, "First Comparison of Stop Value > with/4" + (Math.abs(stopValue) > (listView.getWidth() /4)));
                 Log.d(log, "Second Comparison " + (Math.abs(stopValueY)<VERTICAL_MIN_DISTANCE));
                 Log.d(log, "Action Detected is " + mSwipeDetected + " with Stop Value  " + stopValue);
    
                 if((Math.abs(stopValue) > (listView.getWidth() /4))&&(Math.abs(stopValueY)<VERTICAL_MIN_DISTANCE))
                 {
                     dismiss = true;
                     dismissRight = stopValue > 0;
    
                     if(stopValue>0)
                     {
                     mSwipeDetected = Action.LR;
    
                     }
                     else
                         mSwipeDetected = Action.RL;
                 }
                 Log.d(log, "Action Detected is " + mSwipeDetected + " with Stop Value after dissmiss" + stopValue);
    
                 if(dismiss)
                 {
                     if(dismissRight)
                         mSwipeDetected = Action.LR;
                     else
                         mSwipeDetected = Action.RL;
                     animate(mDownView)
                     .translationX(dismissRight ? listView.getWidth() : - listView.getWidth())
                     .alpha(0)
                     .setDuration(mAnimationTime)
                     .setListener(new AnimatorListenerAdapter() {
                         public void onAnimationEnd(Animator animation)
                         {
    
                         }
                    });
                 }
                 else
                 {
                     animate(mDownView)
                     .translationX(0)
                     .alpha(1)
                     .setDuration(mAnimationTime)
                     .setListener(null);
                 }
    
    
                 break;
    
            }
            }
            return false;
        }
    

    如您所见,我在MotionEvent.ACTION_UP中确定已执行的 Action ,并相应地设置Enum Action的值。如果用户未越过列表 View 边界,则此逻辑就像一个 super 按钮。

    现在,如果用户在滑动(或专门滑动)沿着列表项移动手指时从蓝色变为橙色,则MotionEvent.ACTION_UP将不会提供给listview,这将导致我的代码无法做出决定,并且是由于translationX ()方法和setAlpha(),因为在这种情况下没有确定操作,因此该特定列表项将变为空白。

    问题不会在这里停止,因为,我并不是每次都对 View 进行膨胀,所以每次导致同一空的white/white列表项多次出现时,同一translationX()行也会膨胀。

    有什么办法可以做到,即使我没有遇到MotionEvent.ACTION_UP,我仍然可以做出决定?

    最佳答案

    您应该在return true;中添加case MotionEvent.ACTION_DOWN:,以便对MotionEvent.ACTION_UP进行处理。

    View.OnTouchListener所述:
    MotionEvent.ACTION_UPMotionEvent.ACTION_DOWN发生之前不会被调用,对此的合理解释是,如果ACTION_UP从未出现过,就不可能出现ACTION_DOWN
    此逻辑使开发人员可以在ACTION_DOWN之后阻止其他事件。

    关于android - 不调用MotionEvent.ACTION_UP,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15799839/

    10-10 04:21