You are new to this series? Please start with the first part.
The third part of this series will add some interactivity to our little application. We will add the possibility the icon appears at the point you touch the screen.
Just to remember, we have 3 classes: Tutorial2D (our Activity class), Panel (our SurfaceView class) and TutorialThread (our Thread class).
Our interaction will be handled in our Panel class, so we must be sure, that the touch events will processed by the Panel class. To ensure that, we simply have to set the focus to our panel (line 5).
1 2 3 4 5 6 | public Panel(Context context) { super(context); getHolder().addCallback(this); _thread = new TutorialThread(getHolder(), this); setFocusable(true); } |
To show the bitmap on different locations, we have to add 2 variables for the x and y coordinates and we have to modify the onDraw() method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Panel extends SurfaceView implements SurfaceHolder.Callback { private TutorialThread _thread; private int _x = 20; private int _y = 20; // code snipped @Override public void onDraw(Canvas canvas) { Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.icon); canvas.drawColor(Color.BLACK); canvas.drawBitmap(_scratch, _x, _y, null); } // code snipped } |
Finally we need to override the onTouchEvent() where we get the coordinates of the touch and set our variables.
1 2 3 4 5 6 | @Override public boolean onTouchEvent(MotionEvent event) { _x = (int) event.getX(); _y = (int) event.getY(); return true; } |
Now we can compile and start our application.
You will see, that the application will draw the bitmap not exactly where you touch the screen. The reason is that the coordinates are for the upper left corner of the bitmap. To change that, we have to use a little bit math.
1 2 3 4 5 6 | @Override public void onDraw(Canvas canvas) { Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.icon); canvas.drawColor(Color.BLACK); canvas.drawBitmap(_scratch, _x - (_scratch.getWidth() / 2), _y - (_scratch.getHeight() / 2), null); } |
As you see, we have to subtract half of the bitmap width from x and half of bitmap height from y to get the middle of the bitmap on the point we touched the screen.
Finally our Panel class looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | class Panel extends SurfaceView implements SurfaceHolder.Callback { private TutorialThread _thread; private int _x = 20; private int _y = 20; public Panel(Context context) { super(context); getHolder().addCallback(this); _thread = new TutorialThread(getHolder(), this); setFocusable(true); } @Override public boolean onTouchEvent(MotionEvent event) { _x = (int) event.getX(); _y = (int) event.getY(); return true; } @Override public void onDraw(Canvas canvas) { Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.icon); canvas.drawColor(Color.BLACK); canvas.drawBitmap(_scratch, _x - (_scratch.getWidth() / 2), _y - (_scratch.getHeight() / 2), null); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { _thread.setRunning(true); _thread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // simply copied from sample application LunarLander: // we have to tell thread to shut down & wait for it to finish, or else // it might touch the Surface after we return and explode boolean retry = true; _thread.setRunning(false); while (retry) { try { _thread.join(); retry = false; } catch (InterruptedException e) { // we will try it again and again... } } } } |
Comments
Leave a comment Trackback