获取查看位置

时间:2014-03-10 16:34:55

标签: android view ontouchlistener

我正在开发一个简单的应用程序,在触摸屏幕上产生气泡。气泡在屏幕上移动并在到达屏幕边界或用户触摸时弹出。我已成功将气泡编码到达屏幕边界时弹出,但无法找出检测用户是否触摸它的方法。

我想检测用户是否触摸了屏幕上的任何气泡。

注意: - 使用自定义视图创建气泡。此外,我只包括一些重要的功能,但如果你愿意,可以包括整个代码。这是代码

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's finger
        mXPos = x - mScaledBitmapWidth / 2;
        mYPos = y - mScaledBitmapWidth / 2;

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

        // Set the BubbleView's 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's 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's 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's 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's 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()进行比较,以检测我是否点击任何气泡。我必须检查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 个答案:

答案 0 :(得分:1)

在onSingleTapConfirmed函数中,尝试以下操作来迭代BubbleViews并传递事件X和Y坐标。

for(int i=0;i<mFrame.getChildCount();i++){
    BubbleView bubbleThis = (BubbleView) mFrame.getChildAt(i);
    if (bubbleThis.intersects(event.getX(),event.getY())){
        bubbleThis.stop(true);
        return true;
    }
}

如果X和Y落在其边界内,则BubbleView中的函数应该返回true。我将在BubbleView中的intersects函数中添加函数作为说明:

private synchronized boolean intersects(float x, float y) {
    if ( (x>mXPos && x<(mXPos+mScaledBitmapWidth)) && (y>mYPos && y<(mYPos+mScaledBitmapWidth)) ) {
        return true;
    }
    return false;
}

答案 1 :(得分:0)

如果您想知道用户是否点按了气泡,请设置其onClickListener。如果您想知道用户是否只是触摸了它,请覆盖其onTouchEvent并查找ACTION_DOWN

答案 2 :(得分:0)

答案 3 :(得分:0)

气泡是圆形的,所以你只需要将它的半径与气泡中心和位置之间的距离进行比较。

mRadius =气泡半径

mDistance =(event.getX(),event.getY())和气泡中心之间的距离(mXPos + mRadius,mYPos + mRadius)