无法检测两个视图重叠:DPAD操作误触发成功提示的技术问题
Hey there! Let's fix this annoying issue where your success prompt pops up the second you press a DPAD key—clearly not what you want, since the ball hasn't even moved toward the goal yet.
问题根源
Your current code is triggering the success check the moment you press the key, but the ball's movement happens via ObjectAnimator after that. At the time of the key press, the ball is still in its original position, so either your collision logic is incorrectly passing, or you're showing the prompt without any collision check at all.
解决方案:调整碰撞检测时机
We need to move the collision check to when the ball has actually moved—either once the animation finishes, or in real-time as the ball slides toward the goal.
第一步:编写碰撞检测方法
First, create a helper method to check if the ball overlaps with the goal using their view bounds:
private boolean isBallInGoal() { // Get the bounding rectangles for both views Rect ballBounds = new Rect(); ballImageView.getHitRect(ballBounds); Rect goalBounds = new Rect(); goalImageView.getHitRect(goalBounds); // Check if the two rectangles intersect (change this if you need the ball fully inside the goal) return Rect.intersects(ballBounds, goalBounds); }
第二步:在动画结束后检查碰撞
Modify your onKeyDown method to add an animation listener, so we only check for the goal after the ball finishes moving:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { ObjectAnimator animator; switch(keyCode) { case KeyEvent.KEYCODE_DPAD_RIGHT: // Define the animation to move the ball right animator = ObjectAnimator.ofFloat(ballImageView, "translationX", ballImageView.getTranslationX() + 50); // Add a listener to check the goal after animation ends animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { // Now check if the ball is in the goal if (isBallInGoal()) { Toast.makeText(YourActivity.this, "成功!小球进入球门啦", Toast.LENGTH_SHORT).show(); } } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); animator.start(); return true; // Repeat this pattern for other DPAD keys (left, up, down) case KeyEvent.KEYCODE_DPAD_LEFT: animator = ObjectAnimator.ofFloat(ballImageView, "translationX", ballImageView.getTranslationX() - 50); animator.addListener(/* Reuse the same listener instance to avoid redundancy */); animator.start(); return true; default: return super.onKeyDown(keyCode, event); } }
可选:实时检测碰撞(移动过程中触发提示)
If you want the success prompt to show as soon as the ball touches the goal (instead of waiting for the animation to end), use an AnimatorUpdateListener instead:
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (isBallInGoal()) { Toast.makeText(YourActivity.this, "成功!小球进入球门啦", Toast.LENGTH_SHORT).show(); animator.cancel(); // Optional: stop the animation once the goal is reached } } });
关键提醒
- Replace
YourActivitywith your actual activity class name. - Adjust the movement distance (
+50/-50) to match your app's scale. - If you need the ball to be fully inside the goal (not just touching), modify the
isBallInGoalmethod to checkgoalBounds.contains(ballBounds)instead ofRect.intersects.
内容的提问来源于stack exchange,提问作者Mehdi Haghgoo

