Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android SurfaceView scrolling

I'm writing an android application that builds an offscreen bitmap that is (say) 640*480 pixels and displays that in a SurfaceView. Note that the size of the image is larger than the actual display on the handset.

The way that the application works is that it initially displays the upper left corner (0,0) of the image and then I would like to be able to scroll around the image.

My Surfaceview class implements the onMeasure callback and returns a size of 1024*768 which displays the area of the image that corresponds to the phone screen. I'd like to implement support for scrolling which I'm finding near impossible due to the very limited documentation (just bunches of classes and calls with no coherency). I've tried just calling scrollBy and that doesn't work.

If anyone has any pointers about how to proceed this would be much appreciated.

like image 356
Lee Avatar asked Jul 08 '09 07:07

Lee


2 Answers

Once you start using a SurfaceView, you are moving yourself into a world where you have a blank area of pixels, and you are on your own to draw them how you want. You do everything yourself - and that means you need to implement scrolling yourself as well. It's not trivial to do, but neither is it too difficult.

One way to do it is the following: - Extend SurfaceView and implement SurfaceHolder.Callback - Use getHolder().addCallback( this ) to grab the callback - Use OnTouch events to implement the scrolling behavior (i.e., when responding, pick up the x,y position from the MotionEvent and set the offset appropriately).

Implement a thread to handle the updating of the image. There are examples of this around on the web (sorry - don't have any to hand right now).

Alternatively, use an off-screen bitmap and have it drawn by a normal ImageView (size the ImageView to the size of the bitmap and place it in a scroll view).


Edit:

Seeing that this is still getting views, it might be worth pointing out that since this time, I've implemented and released as open-source a small library that implements a framework for the above functionality (inspired by many comments here on SO, among others). It can be found on Github: https://github.com/micabyte/android_game

like image 141
Michael A. Avatar answered Oct 24 '22 08:10

Michael A.


I just solved this for my own game, my surfaceView is an adaptation of the LunarLander example by Google.

Everything is the same except I'm drawing on my own private Bitmap with my own private Canvas in the doDraw method, and then copying some of it to the canvas I'm given using the code below.

Rect src = new Rect(mScrollX, mScrollY, mScrollX+mSurfaceWidth, mScrollY+mSurfaceHeight);
Rect dst = new Rect(0, 0, mSurfaceWidth, mSurfaceHeight);
surfaceCanvas.drawBitmap (mLevelBitmap, src, dst, null);

The Rect objects define how drawBitmap scales/transforms pixels from the source Bitmap (my private bitmap) to the destination (the Canvas I was given to draw on in doDraw()

mScrollX and Y are the upper left corner of the rectangle that will be displayed (relative to the big private bitmap)

mSurfaceWidth/Height is the size of the rectangle that will be displayed

Just make sure the scroll values are within acceptable ranges [0,privateBitmapWidth-mSurfaceWidth]

update the scroll values yourself however you please, (in onTouchEvent() for example)

like image 42
Nathan Avatar answered Oct 24 '22 09:10

Nathan