Android - 滚动和投掷对话框(DialogFragment)

时间:2014-09-28 18:28:26

标签: android gestures

我有一个用例,我需要帮助我为特殊需求的个人开发一个应用程序。在一个特定用例中,当从列表视图元素中的缩略图图像中选择视频时,应用程序弹出一个对话框(使用DialogFragment),该对话框包含播放视频的VideoView和关闭图标。这是按预期工作的。

但是,我希望弹出式对话框有两种触摸行为:滚动和投掷。这些更重要的行为就是投掷。因此,我希望用户能够移动对话框,如果检测到一个fling,我会关闭对话框。

我检测到这两个事件,但是我在事件的绘图(动画?)上遇到了麻烦。

我目前只在检测到fling时解除对话框(即还没有动画):

    final GestureDetector gesture = new GestureDetector(getActivity(),
            new GestureDetector.SimpleOnGestureListener() {
                private PointF origin = new PointF();

                @Override
                public boolean onDown(MotionEvent e) {
                    origin.x = e.getRawX();
                    origin.y = e.getRawY();
                    return true;
                }

                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                        float velocityY) {
                    Log.d(LOG_TAG, "onFling has been called!");
                    final int SWIPE_MIN_DISTANCE = 120;
                    final int SWIPE_MAX_OFF_PATH = 250;
                    final int SWIPE_THRESHOLD_VELOCITY = 200;
                    try {
                        if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                            return false;
                        if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                                && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                            Log.d(LOG_TAG, "Right to Left");
                        } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                                && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                            Log.d(LOG_TAG, "Left to Right");
                        }
                        dismiss();
                    } catch (Exception e) {
                        // nothing
                    }
                    return super.onFling(e1, e2, velocityX, velocityY);
                }
            });

但是,我尝试过滚动事件的动画,这太可怕了。它闪烁,跳跃和重复。

    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            gesture.onTouchEvent(event);

            final int action = MotionEventCompat.getActionMasked(event);

            switch (action) {
            case MotionEvent.ACTION_DOWN: {
                final int pointerIndex = MotionEventCompat.getActionIndex(event);
                final float x = MotionEventCompat.getX(event, pointerIndex);
                final float y = MotionEventCompat.getY(event, pointerIndex);

                // Remember where we started (for dragging)
                lastTouchX = x;
                lastTouchY = y;
                // Save the ID of this pointer (for dragging)
                activePointerID = MotionEventCompat.getPointerId(event, 0);
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                // Find the index of the active pointer and fetch its
                // position
                final int pointerIndex = MotionEventCompat.findPointerIndex(event,
                        activePointerID);

                final float x = MotionEventCompat.getX(event, pointerIndex);
                final float y = MotionEventCompat.getY(event, pointerIndex);

                // Calculate the distance moved
                final float dx = x - lastTouchX;
                final float dy = y - lastTouchY;

                posX += dx;
                posY += dy;

                moveWindow((int) posX, (int)posY);

                // Remember this touch position for the next move event
                lastTouchX = x;
                lastTouchY = y;

                break;
            }

            case MotionEvent.ACTION_UP: {
                activePointerID = INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_CANCEL: {
                activePointerID = INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_POINTER_UP: {

                final int pointerIndex = MotionEventCompat.getActionIndex(event);
                final int pointerId = MotionEventCompat.getPointerId(event, pointerIndex);

                if (pointerId == activePointerID) {
                    // This was our active pointer going up. Choose a new
                    // active pointer and adjust accordingly.
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    lastTouchX = MotionEventCompat.getX(event, newPointerIndex);
                    lastTouchY = MotionEventCompat.getY(event, newPointerIndex);
                    activePointerID = MotionEventCompat.getPointerId(event, newPointerIndex);
                }
                break;
            }
            }
            return true;
        }
    });

    return view;
}

private void moveWindow(int x, int y) {
    WindowManager.LayoutParams layoutParams = getDialog().getWindow().getAttributes();
    layoutParams.gravity = Gravity.TOP | Gravity.START;
    layoutParams.x = x;
    layoutParams.y = y;
    getDialog().getWindow().setAttributes(layoutParams);
}

在发布此问题之前,我做了大量的研究,并且我知道我应该以某种方式使用OverScroller和动画,但我无法弄清楚如何在我的用例中使用这些。 / p>

关于Fling的说明:对于我的投掷,我只想要与在Android任务(应用程序)视图中将其投放到右边时关闭应用程序时完全相同的用户体验。

感谢您提供任何帮助!

0 个答案:

没有答案