When creating an App users need to somehow interact with your program. Mostly this will include touch support. To set up touch support you need to do the following Warning lots of code !! I will try to explain everything step by step.
Lines 8, 39,73: Listen to the various events.
Line 11-28: When a mouse-down event is detected it means that we are in a new cycle of down->move->up events. In this case it means that we first have find out if the current location was not the previous location and if this is not the case we need to find out if we touched something we are interested in ( 13 ). If so we will do all kinds of stuff with that element and call invalidate. This causes the UI to redraw everything.
Line 39 – 65: If the action_up is detected it means that we are done with our current operation. In this case it means that we have to find out where currently are situated. If that location somehow intersects with another element we are interested in it will cause a change in the ui ( in this case some cards will be redrawn with another image )
73 – 83: Touch support means in most cases drag support. We do this simply by getting our current location and move the current selected element ( a card ) to that new position. Since the x and y coordinates of the event are left/top coordinates we need to change that location so that we don’t touch the top/left corner of that element but somewhat in the middle this feels a bit more natural to the user.
// Add a TouchListener @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "Event : " + event.getAction()); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d(TAG, "X: " + event.getX()); Log.d(TAG, "Y: " + event.getY()); if (event.getX() != this.previousX && event.getY() != this.previousY) { // we changed if (this.touchedMyDeck(event.getX(), event.getY())) { if((myDrawnCard!=null && myDrawnCard.getParent().equals(Card.Empty))|| myDrawnCard == null){ if(myDrawnCard!=null){ myDrawnCard.recycle(); } if (StrategoGame.getInstance().showCurrentCardOnStack() != null) { Card c = StrategoGame.getInstance() .drawCardFromStack(); this.myDrawnCard = new UICard(c, StrategoGame.getInstance().getColor(), getContext(), this.drawnCardX, this.drawnCardY); myDrawnCard.flip(); this.invalidate(); } } } else if (this.touchedDrawnCard(event.getX(), event.getY())) { currentlyTouchedCard = this.myDrawnCard; } } break; case MotionEvent.ACTION_UP: if (currentlyTouchedCard != null) { UICard frontlineCard = null; for (UICard c : this.frontLine) { if (CardUtil.touchedCard(currentlyTouchedCard, c)) { frontlineCard = c; break; } } if (frontlineCard != null) { if (frontlineCard instanceof UICardPlaceHolder) { int index = frontLine.indexOf(frontlineCard); UICard newUICard = (UICard) currentlyTouchedCard.clone(getContext()); if(currentlyTouchedCard.isFlipped()){ newUICard.flip(); } frontLine.set(index, newUICard); this.currentlyTouchedCard = null; this.myDrawnCard = null; } } } // TODO Find out if currentlyDrawnCard is touching frontline. If so // check if frontline is empty location // IF so add this card to that spot in the frontline else move card // to default location. break; case MotionEvent.ACTION_MOVE: if (this.currentlyTouchedCard != null) { this.currentlyTouchedCard.x = (int) event.getX() - (currentlyTouchedCard.getWidth() / 2); this.currentlyTouchedCard.y = (int) event.getY() - (currentlyTouchedCard.getHeight() / 2); } break; } return true; }
This concludes this little blogpost about touch…