Frage

I am trying to implement a piano app , so i have 2 white key images and in between the black key image. The rect is associated with these 3 images, and in onTouchListener method when i press the black key the getHitRect() function gives me all the 3 values and all the 3 sounds play at once. What changes should i make so that only the outer image button i.e. black key co-ordinates should be considered and only that note would be played. It works for the white keys, where the image is not overlapped.

Any help is much appreciated...

  myButtons = new ArrayList<ImageView>(); 
    myButtons.add(img_c);  //white key1
    myButtons.add(img_db); //black key
    myButtons.add(img_d);  //white key2

  getWindow().getDecorView()
    .findViewById(android.R.id.content)
    .setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View arg0, MotionEvent event) {
            int action = event.getAction();

            if (action != MotionEvent.ACTION_DOWN 
                && action != MotionEvent.ACTION_MOVE 
                && action != MotionEvent.ACTION_UP) return false;

            Rect hitRect = new Rect();
            ImageView button;
            for(int i = 0; i < myButtons.size(); i++) {
                button = myButtons.get(i);
                button.getHitRect(hitRect);

           if (hitRect.contains((int)event.getX(), (int)event.getY())) {

            if(action==MotionEvent.ACTION_DOWN)
                    {
                    //play the sound
                    }
  });
War es hilfreich?

Lösung

Rectangles are what they are: rectangular. So a touch-event on your overlapping black button is also either within the hitRect of the left or right white button beneath it (assuming your white buttons don't overlap). This means that a click on a black button is always triggering the underlying white button's sound too (first or last, depending on which side of the middle-axis you hit the black button).

To avoid this, you need to check if a white button's touch-event is also within a black button's hitRect. And if it is, ignore the white button and only trigger the black button. So

if (hitRectWhite.contains((int)event.getX(), (int)event.getY()) && !hitRectBlack.contains((int)event.getX(), (int)event.getY()))

then trigger white and ignore black, otherwise ignore white and trigger black only. Play around with it, this is just an example. This means you will have to change your implementation so that you have the relevant hitRects of the overlapping white AND black buttons at the same time.

To differentiate between white and black you could use tags like this:

private enum ButtonColor {BLACK, WHITE}

img_c.setTag(ButtonColor.WHITE);
img_db.setTag(ButtonColor.BLACK);
img_d.setTag(ButtonColor.WHITE);

// and the check e.g. like this..
if (button.getTag() == ButtonColor.WHITE) {
  ...
}

Maybe you can also make use of methods like contains(), intersects() etc., but above solution should suffice.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top