Получить позицию просмотра

Я разрабатываю простое приложение, создающее пузыри на экране при прикосновении. Bubble перемещается по экрану и выталкивается, когда он достигает границы экрана или пользователь прикасается к нему. Я успешно закодировал пузырь, чтобы выскочить, когда достигнет границ экрана, но не может найти способ определить, коснулся ли он его.

Я хочу определить, коснулся ли пользователь любого пузыря на экране.

Примечание. - Пузыри создаются с использованием пользовательского вида. Кроме того, я включил только некоторые важные функции, но могу включить весь код, если вы хотите. Здесь код

public class BubbleActivity extends Activity {

// These variables are for testing purposes, do not modify
private final static int RANDOM = 0;
private final static int SINGLE = 1;
private final static int STILL = 2;
private static int speedMode = RANDOM;

private static final int MENU_STILL = Menu.FIRST;
private static final int MENU_SINGLE_SPEED = Menu.FIRST + 1;
private static final int MENU_RANDOM_SPEED = Menu.FIRST + 2;

private static final String TAG = "Lab-Graphics";

// Main view
private RelativeLayout mFrame;

// Bubble image
private Bitmap mBitmap;

// Display dimensions
private int mDisplayWidth, mDisplayHeight;

// Sound variables

// AudioManager
private AudioManager mAudioManager;
// SoundPool
private SoundPool mSoundPool;
// ID for the bubble popping sound
private int mSoundID;
// Audio volume
private float mStreamVolume;

// Gesture Detector
private GestureDetector mGestureDetector;

@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

 setContentView(R.layout.main);

 // Set up user interface
 mFrame = (RelativeLayout) findViewById(R.id.frame);

 // Load basic bubble Bitmap
 mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.b64);

}

@Override
protected void onResume() {
 super.onResume();

 // Manage bubble popping sound
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
 super.onWindowFocusChanged(hasFocus);
 if (hasFocus) {

 // Get the size of the display so this view knows where borders are
 mDisplayWidth = mFrame.getWidth();
 mDisplayHeight = mFrame.getHeight();

 }
}

// Set up GestureDetector
private void setupGestureDetector() {

 mGestureDetector = new GestureDetector(this,

 new GestureDetector.SimpleOnGestureListener() {

 // Detecting if user touched bubble here

 @Override
 public boolean onSingleTapConfirmed(MotionEvent event) {

 // Trying to get bubble position but can't just get x=0, y=0 tried
 // many things
 Log.d(TAG,""+((ViewGroup)mFrame).getChildCount());


for(int i=0; i<((ViewGroup)mFrame).getChildCount(); ++i) {
 View nextChild = ((ViewGroup)mFrame).getChildAt(i);
 Rect rect = new Rect();
 nextChild.getLocalVisibleRect(rect);
 int[] location = new int[2];

 nextChild.getLocationOnScreen(location);
 Log.d(TAG, "X = " + location[0] + " Y = " + location[1]);
 }
 if(event.getAction() == MotionEvent.ACTION_DOWN){
 BubbleView bubbleView = new BubbleView(getApplicationContext(), event.getX(),event.getY());
 bubbleView.start();
 mFrame.addView(bubbleView);
 }

 return true;
 }
 });
}

@Override
public boolean onTouchEvent(MotionEvent event) {

 // TODO - delegate the touch to the gestureDetector


 return mGestureDetector.onTouchEvent(event);

}

@Override
protected void onPause() {

 // TODO - Release all SoundPool resources

 super.onPause();
}

// BubbleView is a View that displays a bubble.
// This class handles animating, drawing, popping amongst other actions.
// A new BubbleView is created for each bubble on the display

private class BubbleView extends View {

 private static final int BITMAP_SIZE = 64;
 private static final int REFRESH_RATE = 40;
 private final Paint mPainter = new Paint();
 private ScheduledFuture<!--?--> mMoverFuture;
 private int mScaledBitmapWidth;
 private Bitmap mScaledBitmap;

 // location, speed and direction of the bubble
 private float mXPos, mYPos, mDx, mDy;
 private long mRotate, mDRotate;

 public BubbleView(Context context, float x, float y) {
 super(context);
 log("Creating Bubble at: x:" + x + " y:" + y);

 // Create a new random number generator to
 // randomize size, rotation, speed and direction
 Random r = new Random();

 // Creates the bubble bitmap for this BubbleView
 createScaledBitmap(r);

 // Adjust position to center the bubble under user finger
 mXPos = x - mScaledBitmapWidth / 2;
 mYPos = y - mScaledBitmapWidth / 2;

 // Set the BubbleView speed and direction
 setSpeedAndDirection(r);

 // Set the BubbleView rotation
 setRotation(r);

 mPainter.setAntiAlias(true);

 }


 // Start moving the BubbleView & updating the display
 private void start() {

 // Creates a WorkerThread
 ScheduledExecutorService executor = Executors
 .newScheduledThreadPool(1);

 // Execute the run() in Worker Thread every REFRESH_RATE
 // milliseconds
 // Save reference to this job in mMoverFuture
 mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() {
 @Override
 public void run() {
 // TODO - implement movement logic.
 // Each time this method is run the BubbleView should
 // move one step. If the BubbleView exits the display,
 // stop the BubbleView Worker Thread.
 // Otherwise, request that the BubbleView be redrawn.
 if(!isOutOfView()){
 moveWhileOnScreen();
 }
 else{
 stop(true);
 }

 }
 }, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
 }

 private synchronized boolean intersects(float x, float y) {

 // TODO - Return true if the BubbleView intersects position (x,y)

 return false;
 }

 // Cancel the Bubble movement
 // Remove Bubble from mFrame
 // Play pop sound if the BubbleView was popped

 private void stop(final boolean popped) {

 if (null != mMoverFuture && mMoverFuture.cancel(true)) {

 // This work will be performed on the UI Thread

 mFrame.post(new Runnable() {
 @Override
 public void run() {

 // TODO - Remove the BubbleView from mFrame

 if (popped) {
 log("Pop!");

 // TODO - If the bubble was popped by user,
 // play the popping sound
 mFrame.removeView(BubbleView.this);
 //mMoverFuture.cancel(true);
 mSoundPool.play(mSoundID, 1, 1, 1, 0, 1);
 }

 log("Bubble removed from view!");

 }
 });
 }
 }

 // Change the Bubble speed and direction
 private synchronized void deflect(float velocityX, float velocityY) {
 log("velocity X:" + velocityX + " velocity Y:" + velocityY);

 //TODO - set mDx and mDy to be the new velocities divided by the REFRESH_RATE

 mDx = velocityX/REFRESH_RATE;
 mDy = velocityY/REFRESH_RATE;

 }

 // Draw the Bubble at its current location
 @Override
 protected synchronized void onDraw(Canvas canvas) {

 // TODO - save the canvas
 canvas.save();

 // TODO - increase the rotation of the original image by mDRotate
 mRotate = mRotate + mDRotate;

 // TODO Rotate the canvas by current rotation
 canvas.rotate(mRotate, mXPos + mScaledBitmapWidth/2, mYPos + mScaledBitmapWidth/2);

 // TODO - draw the bitmap at it new location
 canvas.drawBitmap(mScaledBitmap, mXPos, mYPos,mPainter);


 // TODO - restore the canvas
 canvas.restore();



 }


 private synchronized boolean moveWhileOnScreen() {

 // TODO - Move the BubbleView
 // Returns true if the BubbleView has exited the screen
 mXPos = mDx+mXPos;
 mYPos = mDy+mYPos;

 postInvalidate();
 return false;
 }

 private boolean isOutOfView() {

 // TODO - Return true if the BubbleView has exited the screen
 if(mXPos + mScaledBitmapWidth/2 >= mDisplayWidth - mScaledBitmapWidth/2 || mXPos <0
 ||mYPos + mScaledBitmapWidth/2 >= mDisplayHeight - mScaledBitmapWidth/2 || mYPos <0){
 return true;
 }
 return false;

 }
}

Обновить :-

Чтобы немного прояснить, я хочу получить местоположение всех пузырьков на экране, а затем сравнить их с event.getX() и event.getY(), чтобы обнаружить, что я нажал на любой пузырь. II необходимо проверить пузырьковый кран в onSingleTapConfirmed(). Я правильно могу получить общее количество пузырьков, но не могу определить их местоположение на экране.

for(int i=0; i<((ViewGroup)mFrame).getChildCount(); ++i) {
 View nextChild = ((ViewGroup)mFrame).getChildAt(i);
 Rect rect = new Rect();
 nextChild.getLocalVisibleRect(rect);
 int[] location = new int[2];

 nextChild.getLocationOnScreen(location);
 Log.d(TAG, "X = " + location[0] + " Y = " + location[1]);
 }

Выше кода дает правильное количество пузырьков, но возвращает их координаты как 0,0.

4 ответа

В вашей функции onSingleTapConfirmed попробуйте выполнить следующее, чтобы выполнить итерацию через BubbleViews и передать координаты событий X и Y.

for(int i=0;i
<p> Функция в BubbleView должна возвращать значение true, если X и Y попадают в его границы. Я добавлю функцию внутри функции пересечений в BubbleView в качестве пояснения:</p> <pre class="prettyprint linenums">private synchronized boolean intersects(float x, float y) { if ( (x>mXPos && x<(mXPos+mScaledBitmapWidth)) && (y>mYPos && y<(mYPos+mScaledBitmapWidth)) ) { return true; } return false; } </pre>


Пузырь имеет круг в форме, поэтому вам просто нужно сравнить его радиус с расстоянием между центром пузырьков и положением.

mRadius = радиус пузыря

mDistance = расстояние между (event.getX(), event.getY()) и центром пузырьков (mXPos + mRadius, mYPos + mRadius)


Как вы реализуете метод onDown() вашего SimpleOnGestureListener?

Пожалуйста, взгляните на эти ответы: Детектор жестов не работает

Android GestureDetector с SimpleOnGestureListener в SurfaceView

Определить, какой вид был использован в методе onSingleTapConfirmed


Если вы хотите узнать, нажал ли пользователь пузырь, установите его onClickListener. Если вы хотите узнать, коснулся ли пользователь, переопределите его onTouchEvent и найдите ACTION_DOWN.

licensed under cc by-sa 3.0 with attribution.