我有一个用例,我需要帮助我为特殊需求的个人开发一个应用程序。在一个特定用例中,当从列表视图元素中的缩略图图像中选择视频时,应用程序弹出一个对话框(使用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任务(应用程序)视图中将其投放到右边时关闭应用程序时完全相同的用户体验。
感谢您提供任何帮助!