I am looking for a robust way to scale my AIR for Android app up, or down, for different screen sizes.
The app is going to be published privately, and will only likely ever sit on devices with a very small range of resolutions (720 or 1080p typically)
Now, firstly, I read that you cannot change the stage height and width dynamically and can only be set once in the application settings. So first off, do I set my app to have the largest resolution, 1080p, and scale down. Or do I set it to a mid ground between 1080 and 720 and let it scale up and down?
Secondly, how should I scale it? Should I use Stage.scaleMode and if so, which mode?
How do I scale the app if I cannot resize the stage directly?
I have looked at the following pages, but they don't seem to work very well, if at all, for some odd reason?
link 1
link 2
link 3
link 4
You can do everything dynamically!
use:
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT
and handle it yourself when the application starts. By useing relative values instead of fixed pixels, to position your items
To get the devices dimensions and DPI use:
Capabilities.screenResolutionX;
Capabilities.screenResolutionY;
Capabilities.screenDPI;
If you're useing Bitmaps dont let them scale too much, and rather down then up.
Also checkout .smoothing attribute for Bitmaps.
its best to have different size bitmaps ready and replace them according to your screensize in some startup method.
the second link u postet acutally explains all this very well
Related
I am developing an Android application where the server sends all the values corresponding to dimensions in pixels for 1920*1080 resolution device.I need the app to be supported on multiple screen resolutions.I went through Android documentation on supporting multiple screen resolutions.It suggests to convert pixels to dip and then render.I did that in my application but the views are not rendered as required.So I tried applying simple unitary method by dynamically getting the screen width and height and then scaling all dimensions based on current screen width and height.
Say my current screen width is X and height is Y.So what I did was
Scaling factor in horizontal direction = New Screen Width/1920.
Scaled dimension in horizontal direction = Scaling factor in horizontal direction * Dimension from server in horizontal direction.
Similarly for vertical direction.
The application is now looking fine on my device.But is it a reliable way of doing things ? Should I be dealing with density of display too ?
DP is probably the better approach, if you elaborate a bit on what you mean by 'not rendered as required' I can try to help.
I can think of two main issues with your current method:
Different aspect ratios of devices. Using your method you will end up with distorted imagery. For example a square in 'server dimensions' is 400x400. In a 800x480 phone, that square will be 162x177 - no longer a square. Depending on your visuals and purpose of your app, this may or may not be an issue. If it is an issue, you need to account for that.
Physical views' size. One of the purposes of the DP method is to ensure a view will have (almost ) the same size across different devices, mainly never too small to handle for the user. So using the DP approach, a 100dp button will be 200px on a high density device, and 100px on a medium density device. This way the button is physically the same size on both devices.
But your method ignores that. Take the square from the first example - it will always be a fifth (400/1920) of the width of the screen. This can be either huge or tiny, depending on the device dimensions. Again, depending on your needs this may or may not be a problem.
Your method can work, as long as you account for these (and maybe more) problems. But it does require special care and probably more coding and work to make it work perfectly compared to simply using DP.
I've built an AS3 game with a stage size of 480 by 800, but I still get small margins on the top and bottom. I haven't made any coding relating to screen size cause I understand that 480x800 is the screen size that should fit exactly to the samsung 3 and 4 screen. I don't need it to fit other screens at the moment nor do I need it to orient (just portrait).
I read that the screen ratio is 9:16 so I tried with a stage of 422x750 but I still got margins!
How do I get rid of these margins? Is there a stage size that would fit the screen without coding or do I have to put some code for that?
Check out stage.fullScreenWidth and stage.fullScreenHeight. These 2 properties work alright for me both on Android and iOS (unlike stage.stageWidth and stage.stageHeight).
Sorry but i cant understand how i can draw a right picture for the right android phone size.
I readed the android documentation, and they say for i just think in screen size and density and not in resolution, so what size should have my picture?
For example,if i have a phone with size 1000x400(stupid example),and want a button(40x40) that will be in middle,what size should i do?? 40x40?? But in documention they say for dont look for resolution :\
Im confuse...
ps: The documention link Android multiple screens
Basically you'll have to realize that although resolution, screen size and screen density are separate attributes, they are still somewhat related. If your button is 40x40 as you mentioned, and that's the size you find looks good in the center on a hdpi(high density) device, you will have to scale it so that it fits accordingly on mdpi(medium density) and xhdpi(extra high density) devices. What I like to do is use PhotoShop or another graphical editor and resize my assets so that they fit on whatever density devices I'm trying to target. I make sure to always use *WRAP_CONTENT* for my height and width attributes and never fixed values.
Also, if you do not include these scaled alternatives in your res/drawable folders..you're basically saying that you're relying on the system to scale them for you, which can be a gamble. So I always go with resizing my assets so that I include a version for all densities. The link you posed explains everything pretty well
I have traveled all over the internet looking for a way to do something that I thought would be very basic. Bottom line is: I have an android UI that I have designed. It consists of buttons that are placed along the middle of the screen. This is sort of a menu screen. These buttons need to be in the SAME location but should just increase or decrease in size in relation to the physical size of the screen. Basically, if i have a button on a screen that is 1px (or dip; dip is what i currently use in my application) X 1px, then, if i double the screen size, the button should auto-format to 2px X 2px. I have done the math on my application. The button that I have is about 225/854 down the screen (this comes out to be about 26.44% from the top.) All I want to do is make that button come down the same amount. Say I reduced the size of the screen to 500, the ratio should stay the same.
Example math work:
(225 dip/854 px)*100=26.44%
so if I reduce the screen size to 500px, the dip should be as follows.
(225dip/854px)*500px = 131.733021077283372 dip
Is this the best way to go about scaling my buttons? If so, how do I tell my application to calculate the correct number of dip that the button should be placed at?
If you are still confused (sorry!), here is a key to looking at that work.
225dip = how far the button comes down from the top of the screen.
854px = physical size (in pixels) of the screen
131.733021077283372 dip = new number of dip if screen is reduced to 500px physical size
You can use the WindowManager to get the screen size. In your activity:
getWindow().getWindowManager().getDefaultDisplay().getWidth();
or getHeight() in your case. Once you have that, just do your math, and then:
ViewGroup.LayoutParams buttonLayout = yourButton.getLayoutParams();
buttonLayout.height = 42; // Set your height
buttonLayout.y = 42; //Set distance from top of the screen
and so on. Once done:
yourButton.setLayoutParams(buttonLayout);
Let me know if this works.
If you design your interface using dip (or dp) and sp units (for fonts) you can let Android do the scaling for you. Although maybe not pixel perfect on every device, your app will certainly look the same on many devices in the correct scale.
Supporting multiple screens on http://d.android.com describes this...
I am a bit new to android, although, in the game I am creating I found that it is easiest to allow android to determine the dpi(dots per inch) of the screen and choose my images accordingly.
For example, my games res folder has folders listed as drawable, drawable-hdpi, and more. These folder are here for you to put the corresponding images in for the type of screen.
In the android manifest you can list what screen dpi you support and those folders will be used correctly.
Hope this helps!
EDIT: I would definitely check out this doc page
http://developer.android.com/guide/practices/screens_support.html
This is one of those annoying cases where things are working but I don't know why. Based on the Android API docs and this site, I expected to have to do pixel density conversions on my layout parameters (shown here in their original state):
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.width = 60; // the following three should be pixels, right??
lp.height = 80;
lp.setMargins(1, 5, 1, 5);
In other words, I expected the above to not work well across different screen densities since they're specified in pixels. The "problem" is that it works fine on all of the simulators I've tried, from a lowly QVGA on up. To try to understand why, I used Hierarchy Viewer to inspect my app and found that the width of the view (from getWidth()) was always 320 when my app had focus. Go back to the home screen, say, and now HV reports the screen width as 480.
Any idea what's going on?
The values are indeed specified in pixels. It sounds like your app is running in compatibility mode?
According to http://developer.android.com/guide/practices/screens%5Fsupport.html , if you don't declare support for multiple densities in your Manifest, then it will report medium resolution and the application will behave as such. Says:
If the application states that it does
not support different screen
densities, the platform auto-scales
any absolute pixel coordinates, pixel
dimension values, and pixel math used
in the application (such as might be
used for specifying the width or
padding for a view). It does this to
ensure that pixel-defined screen
elements are displayed at
approximately the same physical size
as they would be at the baseline
density of "medium" (160). The
platform handles this scaling
transparently to the application and
also reports scaled overall pixel
dimensions to the application, rather
than physical pixel dimensions.
For instance, suppose a given device
is
using a WVGA high-denisty screen,
which is 480x800 and about the same
size as a traditional HVGA screen, but
it's running an app that states that
it does not support multiple
densities. In this case, the system
will "lie" to the application when it
queries for screen dimensions, and
report 320x533. Then, when the app
does drawing operations, such as
invalidating the rectangle from
(10,10) to (100, 100), the system will
likewise automatically transform the
coordinates by scaling them the
appropriate amount, and actually
invalidate the region (15,15) to (150,
150). The same thing happens in the
other direction, if the application is
running on a lower-density screen,
coordinates are scaled down.
This is something I have also been working on recently. Is it the anyDensity tag that you are talking about within ?
If so, where is it suppsed to appear in the Manifest?
Regards,
Oliver