views:

209

answers:

3

My Android app (a text-based games) uses background images a lot in order to provide a better visual ambience. For example, if the action in the game takes you into a tavern, then you get a background image of a tavern in the game. This is a vast improvement, graphically, over the boring black background that you would otherwise get.

It is also a problem, however, since android:background always stretches to the dimensions of the screen. The result is that the background images look very bad if the player swithces between portrait and landscape mode. And to make matters worse, many devices have very different aspect rations (e.g., 320x480 mdpi, 480x800 hdpi, and 480x852 hdpi) and even more variations are coming.

How do others solve this problem? Having individual images for the main resolutions/orientations is not an option for me, as this would result in the apk growing too large.

+1  A: 

I would suggest you get the width and height of your current view. Right now I am not sure what functions will give you these values but I am sure it is possible. With that you can then calculate an aspect ration. I'd make the images something like 1000x1000 and just show a certain part of the image, so that the aspect ratio will not be wrong.
I have the same problem with the camera. So my solution was to pick one of the two values, width or height, as fixed and calculate the correct other value according to the aspect ratio. I'm not sure if there are functions already to just show a part of the image, but I am sure you could write something to copy just a part of the image and show that part.

The drawback is of course that you will be showing just a part of the background. Since the general aspect ratio of the phones is however somewhere between 1:1.3 and 1:1.8 I guess it wouldn't be a too big problem. I for one would rather see the part of an image in the correct way, than looking at some ugly stretched image ;)

Pandoro
+1  A: 

Maybe you could create your background images as NinePatch images so that you are in better control of how it stretches? http://developer.android.com/guide/developing/tools/draw9patch.html http://www.developer.com/ws/other/article.php/3889086/Working-with-NinePatch-Stretchable-Graphics-in-Android.htm

Otherwise, you can just prevent your images from stretching (or at least keep the correct aspect ratio) by setting the scaleType attribute e.g. android:scaleType="center". http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

antonyt
+1  A: 

The first step is to get the screen height and width of the device itself, then stretch/shrink or pad your bitmap as needed. This SO answer has source that should help, copied below. Props to Josef for original answer.

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

Here's generic source on getting the orientation.

int orientation = display.getOrientation(); 

or some more involved source from here (a little messy but looks correct).

public int getscrOrientation()
{
  Display getOrient = getWindowManager().getDefaultDisplay();

  int orientation = getOrient.getOrientation();

  // Sometimes you may get undefined orientation Value is 0
  // simple logic solves the problem compare the screen
  // X,Y Co-ordinates and determine the Orientation in such cases
  if(orientation==Configuration.ORIENTATION_UNDEFINED){

      Configuration config = getResources().getConfiguration();
      orientation = config.orientation;

      if(orientation==Configuration.ORIENTATION_UNDEFINED){
        //if height and widht of screen are equal then
        // it is square orientation
            if(getOrient.getWidth()==getOrient.getHeight()){
            orientation = Configuration.ORIENTATION_SQUARE;
            }else{ //if widht is less than height than it is portrait

                if(getOrient.getWidth() < getOrient.getHeight()){
                orientation = Configuration.ORIENTATION_PORTRAIT;
                }else{ // if it is not any of the above it will defineitly be landscape
                orientation = Configuration.ORIENTATION_LANDSCAPE;
                }
            }
       }
  }
  return orientation; // return value 1 is portrait and 2 is Landscape Mode
}
gary comtois