Defining and Updating the Selection

First we're going to implement a little cursor that shows the player which tile is currently selected. The selected tile is the one that will be modified when the player enters a number. This code will draw the selection in onDraw( ):

Download Sudokuv2/src/org/example/sudoku/PuzzleView.java

// Draw the selection... Log.d(TAG, "selRect=" + selRect); Paint selected = new Paint(); selected.setColor(getResources().getColor(

R.color.puzzle_selected)); canvas.drawRect(selRect, selected);

We use the selection rectangle calculated earlier in onSizeChanged( ) to draw an alpha-blended color on top of the selected tile.

Figure 4.5: Drawing and moving the selection

Next we provide a way to move the selection by overriding the onKey-Down() method:

Download Sudokuv2/src/org/example/sudoku/PuzzleView.java

@Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.d(TAG, "onKeyDown: keycode=" + keyCode + ", event="

+ event); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: select(selX, selY - 1); break;

case KeyEvent.KEYCODE_DPAD_DOWN: select(selX, selY + 1); break;

case KeyEvent.KEYCODE_DPAD_LEFT: select(selX - 1, selY); break;

case KeyEvent.KEYCODE_DPAD_RIGHT: select(selX + 1, selY); break; default:

return super.onKeyDown(keyCode, event);

return true;

If the user has a directional pad (D-pad) and they press the up, down, left, or right button, we call select( ) to move the selection cursor in that direction.

How about a trackball? We could override the onTrackballEvent() method, but it turns out that if you don't handle trackball events, Android will translate them into D-pad events automatically. Therefore, we can leave it out for this example.

Inside the select( ) method, we calculate the new x and y coordinates of the selection and then use getRect( ) again to calculate the new selection rectangle.

Download Sudokuv2/src/org/example/sudoku/PuzzleView.java

private void select(int x, int y) {

i nvalidate(selRect);

getRect(selX, selY, selRect);

invalidate(selRect);

Notice the two calls to invalidate(). The first one tells Android that the area covered by the old selection rectangle (on the left of Figure 4.5, on the previous page) needs to be redrawn. The second invalidate( ) call says that the new selection area (on the right of the figure) needs to be redrawn too. We don't actually draw anything here.

This is an important point: never call any drawing functions except in the onDraw() method. Instead, you use the invalidate() method to mark rectangles as dirty. The window manager will combine all the dirty rectangles at some point in the future and call onDraw() again for you. The dirty rectangles become the clip region, so screen updates are optimized to only those areas that change.

Now let's provide a way for the player to enter a new number on the selected tile.

0 0

Post a comment