# Fitting Android game to different screen sizes

I am making an Android game that is only in portrait screen orientation. It works great when I run it on my phone, but when I run it on a tablet, even though the screen size is bigger, all of the bitmaps are the same size. Is there any way to make the bitmaps stay the same proportion even on different size screens?

Unless you're using AbsoluteLayout (Usually a very bad idea, as you design your layout using x/y coordinates, which will only suit the device it's been designed on) this should not happen - Android applications automatically adjust to the device's screen-size. However from what you describe (Layout does not adjust to Table Screen), it sounds like AbsoluteLayout might be the issue here.

Make sure that in your layout XML files you're NOT using absolute layouts (this includes setting explicit coordinates/widths/heights on any kind of View). Instead consider using:

• LinearLayout - Stacks multiple views horizontally or vertically
• FrameLayout - Usually contains one Child
• RelativeLayout - Align children relative to each other
• TableLayout - A Table-based layout
• ScrollView - May contain one child item (such as a LinearLayout) and lets you scroll it's content

... whatever best suits your purpose.

If you're new to Android, then Google offers a nice tutorial that introduces to the different Layout Types mentioned above. More tutorials can be found here.

Furthermore your API Level would be relevant (to know whether you're using Android 2.x or 4.x - I don't assume 3.x as it's not available for Smartphones) to figure out the cause of your issue.

Are you forcing your Application into Portrait mode by setting:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set screen orientation for this dialog to portrait
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}


... in your Activity that displays the game's views?

Please provide more info on how you're layouting your views (are you using XML for the layout that you later inflate in your Activity, or are you using in-code layouting in your Activity etc....) ? Furthermore: Did you try running your app in a Smartphone - and Tablet-sized Emulator? If yes, does the issue persist?

UPDATE: HOW TO SCALE BITMAPS

The OP asked how he can scale the bitmap's he's using in his game. One option (from all I know about the OP's setup): The SurfaceHolder.Callback that you're overriding to display your game and on which you render all the Bitmaps etc... has a method called:

surfaceChanged(SurfaceHolder holder, int format, int width, int height)


That method gives you the width/height of your surface, so you could now use:

Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)


from the Bitmap class. To resize your images in proportion to the size of the surface you're drawing onto.

What you need to do is this: If you know the dimensions of your bitmap in relation to a given screensize, for instance the screen-size of your smartphone. Then you can calculate the target dimensions of the scaled bitmaps. Here is the math (wrapped in an example):

Say you have a Bitmap A with the dimensions 25x50 (widthxheight) which is displayed on a screen with the dimensions 100x200 (widthxheight). For that screen size (100x200) the bitmap has the correct dimensions - now if you want to display the bitmap on a larger screen you need to:

• Calculate the scale factor for the bitmap size
• Maintain the aspect ratio of the bitmap (so it does not get distorted)

Say the larger screen is 200x300 (widthxheight) then the scale-factor for the width is:

200(target screen width)/100(default screen width) = 2


So 2 is our scale-factor for the width and height value of the bitmap, since we need to maintain the aspect ratio of the bitmap, we can simply multiply the scale factor with the width and height of the bitmap:

bitmapWidth * 2 = scaledBitmapWidth
bitmapHeight * 2 = scaledBitmapHeight


So using our example bitmap A from above and the mentioned formula, the new dimensions of the bitmap would be: 50x100 (widthxheight) because:

 2*25(width) = 50 height
2*50(height) = 100 height


Soo now that we know the new size of our bitmap we simply use the API call I mentioned above and fill in the blanks:

   Bitmap.createScaledBitmap (myBitmap, 50, 100, false)


myBitmap in the above example is the original bitmap A that had the dimensions 25x50 and is scaled to 50x100 using the above code-snippet.

However - this wouldn't solve your original issue of the application taking up only the upper right corner of a tablet-sized device. To answer that one we'd require answers to the questions we asked you regarding your setup. I'll quickly sum them up here:

• Are you using a game-engine such as AndEngine or Unity ?
• You mentioned that you're implementing SurfaceHolder.Callback? The width/height provided in the method call of surfaceChanged gives you the size of the surface - is it the same size when your app runs on a smartphone or a tablet?
• Do you have any access to the SurfaceView (or whatever is linked to that SurfaceHolder.Callback you're implementing), so we could determine if that's the one rigidly setting the app size to smartphone size.
• Do the same resize-issues occur in the emulator with different screen resolutions?

A general suspicion: Not every smartphone has the same screen size, in fact there's a wide range of screen sizes, which makes me wonder: Did u ever test your app on a smartphone with a different screen size than your screen? Because - the fact that it fits your screen, but not a tablet, makes me wonder who sets those dimensions and when. Because I doubt that an app can adjust to all smartphone-screen-sizes, but not to tablet sizes - won't make much sense (because they more or less have the same android core running on them, some differences between s.x, 3.x and 4.x aside) UNLESS you're using a framework which does not support (for whatever reason - maybe you'd have to buy tablet support extra or whatever) tablet-sized screen sizes. That's why it's really important to know, whether the app resizes properly on your phone only, or on other smartphones as well. The only way I am aware of how an app can be limited to the screen size of one specific phone is by using AbsoluteLayout and generally absolute dimensions for widgets etc...

UPDATE: Scaling x/y Coordinates

In order to adjust your bitmap's location to the screen size, something like the following should do the job:

• Screen dimensions: 100/200 (width/height)
• Bitmap location: x=50/y=100

Now, if you increase the screen size, you'd have to scale those x/y values along:

• Screen dimensions: 200/400 (width/height)

The scale factor would be 2, because the width and height equally increased by two. Hence the dimensions would be...

• Bitmap location: x=100/y=200

Another try - this time with different scale factors for width/height

• Screen dimensions: 100/150 (width/height)
• Bitmap location: x=50/y=50

If the new target screen is 150/250 then calculations are:

• Scale factor for width = targetWidth / originalWidth = 1.5
• Scale factor for height = targetHeight / originalHeight = 1.666... (Period)

Now we need to scale the x/y coordinates, x is scaled using the width-scale and height is scaled using the height-scale, here's the result:

• x = originalX * 1.5 = 75
• y = originalY * 1.666.. (Period) = 83.333... (Period)

So the new screen dimensions and the scaled x/y coordinates are:

• width = 150
• height = 250
• x = 75
• y = 83,333... (Period)

To make a long story short, the algorithm for scaling bitmaps is:

X = (targetScreenWidth / defaultScreenWidth) * defaultXCoordinate
Y = (targetScreenHeight / defaultScreenHeight) * defaultYCoordinate

• My game uses a game panel that extends SurfaceHolder.Callback (It's in an XML file that is called by an Activity). Could this be part of the problem? – user1404512 May 29 '12 at 22:21
• @user1404512 A SurfaceHolder.Callback is usually linked to a SurfaceView - and it also depends on how that SurfaceView is configured (width/height) if it's embedded in another Layout (like FrameLayout etc.)... in your A SurfaceHolder.Callback there should be a method: public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) the width and height should be the size of what's being drawn on screen - which in your case would be the same on tablets & smartphones - can you verify that? – AgentKnopf May 30 '12 at 6:06
• Yes, I think I should say this: When I run it on my tablet, even though the screen size is bigger, all of the bitmaps are the same size. Is there any way to make the bitmaps stay the same proportion even on different size screens? – user1404512 May 30 '12 at 19:31
• @user1404512 It's really important, that you answer all those questions we asked you, because we're still kind of in the dark as to how your layout is designed, which makes it difficult to answer any specific question. As for your bitmaps: I updated my answer to answer the bitmap-scaling question the best I could, given that very little is known about your setup. – AgentKnopf May 31 '12 at 5:03
• No, I am not using a game engine. I do have my layout in xml, and in my xml file I have a SurfaceHolder.Callback that is the entire screen. The width and height of the holder change from screen to screen. I think that my problem is that I am drawing the bitmaps with X and Y coordinates, but the scale of the bitmaps stays the same from screen to screen. Is there any way to fix this? Thanks a lot in advance! – user1404512 Jun 2 '12 at 0:14

There is a good and relevant article on Android.com : http://developer.android.com/guide/practices/screens_support.html

This reference helps you sort through screen size, screen density, and resolution. The goal is to use the Android APIs to achieve "density independence" so that your user interface components and graphics can look good on various devices.

Remember that you can also create different configurations of Android Virtual Devices for the emulator while you're testing layout and appearance: http://developer.android.com/guide/developing/devices/emulator.html

Just a shot in the dark here. Have you set whatever the master layout is to fill parent both vertically and horizontally?