本文介绍了不调用MotionEvent.ACTION_UP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

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

Consider the following scheme below (for sake of better understanding of my problem).

如您所见,我正在考虑一个由填充包围的列表视图.现在,如果用户按下一个列表视图项,则我提供的操作是浅蓝色背景色.现在,我的应用程序正在处理onTouch事件本身,以确定类似的动作

As you can see, I am considering a list view surrounded by padding. Now, If a user presses a listview item, as the action I have provided it light blue background color. Now, My application is dealing with onTouch Events itself to determine actions like

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

这是我的代码.

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中确定已执行的动作,并相应地设置Enum Action的值.如果用户未越过列表视图边界,则此逻辑就像一个超级按钮.

As you can see, I determine the performed action in MotionEvent.ACTION_UP and set the value of Enum Action accordingly. This logic works like a charm if the user does not crosses the list view boundary.

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

Now, if the user, while sliding (or specifically), moving his finger along the list item moves from blue to orange, the MotionEvent.ACTION_UP would not be given to listview, which causes my code not to make a decision and due to translationX() method and setAlpha(), since no Action is ever determined in this case, that particular list item gets blank.

问题不会在这里停止,因为,我并不是每次都在夸大视图,每次都会导致相同的translationX()行被夸大,从而导致多次出现空白/白名单项目.

The problem does not stops here, since, I am not inflating view each time, same translatedX() row gets inflated each time leading to multiple occurance of a blank/white list item.

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

Is there anything possible to do so that even if I didn't encounter MotionEvent.ACTION_UP, I could still make some decison ?

推荐答案

您应该在case MotionEvent.ACTION_DOWN:中使用return true;,以便处理MotionEvent.ACTION_UP.

You should return true; in case MotionEvent.ACTION_DOWN:, so the MotionEvent.ACTION_UP will be handled.

View.OnTouchListener 所述:

如果侦听器已经使用了事件,则为真,否则为false.

True if the listener has consumed the event, false otherwise.

MotionEvent.ACTION_UPMotionEvent.ACTION_DOWN出现之前不会被调用,对此的逻辑解释是,如果ACTION_UP从未出现过,则ACTION_UP不可能出现.

MotionEvent.ACTION_UP Won't get called until the MotionEvent.ACTION_DOWN occurred, a logical explanation for this is that it's impossible for an ACTION_UP to occur if an ACTION_DOWN never occurred before it.

此逻辑使开发人员可以在ACTION_DOWN之后阻止其他事件.

This logic enables the developer to block further events after ACTION_DOWN.

这篇关于不调用MotionEvent.ACTION_UP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 07:34