Proper usage of metrics with Kivy(So GUI scales well across devices) - android

I am trying to get my game to look/scale well across different devices. I am attempting to introduce the dp and sp metrics into my apps as much as possible, but in this case I am refactoring a game to use these metrics for layout and widget sizing.
Where before, my layouts were sized using size_hint in order to have everything get it's size relative to it's parent(the app itself is not given a size, nor is the window, but the root widget/layout has size_hint=(1, 1)), I am now faced with replacing this system with dp values, and can't figure out what they should be.
I am thinking, that if I just size the root widget, App itself, or Window with dp, then I could continue to use size_hinting, as this would have a trickle down effect and scale everything correctly from the top on down, so to speak. And for this, It seemed like getting the resolution or density of a devices screen would be a great help(so I could use it to size my root widget/App/Window, per device). Is that possible with Kivy? Will this work? Is there a better way? What would you do? Thanks

Using size_hint alone already guarantees a degree of scale independence, as (as you note) all the sizes will be relative.
Kivy internally checks some resolution related values of the device, and this is basically the point of dp; something like dp(10) for instance should be the same actual size on any device, in terms of real size on the screen in e.g. centimetres. This won't actually be quite right, if nothing else I think devices don't report precisely right results, but unless this is very important it will already take care of making things mostly look the same anywhere.
I'm not sure what you mean about setting the App size - in Android's window manager an App just fills the screen (at least in most cases).

Related

libgdx -> camera and viewports

I have made my game, which scaled accordingly to a % of the screen width with the Gdx.graphics.getWidth() method, and it works perfectly on all screens.
Now I am trying to learn viewports, but seems like there is a lot more trouble, like when does it take in world coordinated or when does it take actual screen pixels.
Do I have to constantly convert beetwen these two measurments? It seems like there is alot more trouble, than if I just scale it the old fasion way...
I can use the whole screen, and manually make the pictures non streched, if I used a FitViewport I would have like blackbars and the game would be totally different.
Any clear suggestions to why to use these ports, cause I cannot seem to understand them...
The thing is that you do not have to do anything especially making any conversion.
Viewport is a kind of tool that handling your app's rendering on many types of screens (I mean many other ratios) and you do not have to worry about it anymore.
Only thing you have to do is to "tell" viewport what is the size of your screen and to handle screen resizing by updateing the viewport. Then you are treating your app like it would be always for example 800 x 600px no matter how it looks actually.
The way your app will render depends on what viewport implementation you will use. For example:
FitViewport will fit your screen to device and add some black bars
FillViewport will fit your screen to device and cut off overflowing part
and so on...
The a look at official Viewport libGDX tutorial. Also you can take a look at this thread to get some information how to deal with viewports.

How can I ensure that my app is compatible with every Android device and will scale views to fit different screen dimensions?

I'm in the beginning stages of developing my first app and wanted to know what I can do from now to make sure my app runs equally well across all Android devices. I don't have access to another device right now to test whether or not it will scale but have I noticed that if I rotate my device to landscape, the items in the view (e.g. buttons, icons) don't scale at all to fit the screen. This makes me worry that it won't be very compatible with other devices.
I find myself putting items in each view by messing with paddings and margins in the XML till I have it right - but now I realise that this makes the layouts specific to my device. Is there a "correct" way of doin this? For instance, if I had to draw 4 horizontal lines equally spaced across the width of a screen how would I achieve this so that the width between the lines are determined according to the size of the screen?
I have a large image in my MainActivity but for some reason it gets really small if I switch to landscape.
Can anybody shed some light on this? Would be really grateful, thanks.
This issue is addressed here:
http://developer.android.com/guide/practices/screens_support.html

Android: Doing all my drawing on a SurfaceView; what's the proper way of making sure my drawing conforms to any screen size?

I'm making an app (a game, to be exact) where each activity uses a SurfaceView for the UI. All of the drawing is done through onDraw. I am also designing this to use no Bitmap assets, so everything that is drawn is produced directly by the app. I'm trying to design the app in such a way that it can easily be viewed on any screen size.
So here's how I'm accomplishing this: I'm doing my testing on a Galaxy S4, which has a screen size of 1080x1920. In the constructor for each activity, the width and height of the current screen are calculated and stored as ints "w" and "h" (the app is already locked in portrait). Then, whenever anything needs to be drawn onto the screen, I multiply the desired dimension (as seen on my 1080x1920 screen) by either w or h, and then divide by 1080 or 1920. Since I'm not using any Bitmap assets, I never need to worry about pixelated images or anything this way.
This gets the job done, but seems like a bit of a roundabout way of doing it. I figured there would be a better framework for getting this done, and I'm worried that these big calculations are eating into my drawing time (running at 30FPS can get a little jerky).
Is this is the customary way of doing it, or is there a better way out there?
There's a very simple yet effective way to do it, you can declare all your sizes in a dimen file for each specific density/size, as you usually do for layouts e.g:
values/dimens.xml <--- With default sizes
values-sw600dp/dimens.xml <-- Tablets sizes
(etc...)
Now before you start drawing, load all the values in your program only once, maybe onCreate of your drawing activity, using the following command:
float someItemSize = Context.getResources().getDimension(R.dimen.some_itemSize)
etc...
That way, you let the operating system do the pixels conversion for you, you should do it only once and most important, this will give alot of flexibility to your code because you will be able to change sizes from xml files without even touching your actual code, hence, the customization should be easier as well as future changes...
Hope it helps!
Regards!
There are two considerations: screen size and screen aspect ratio. If you simply scale everything to match the display, you will appear stretched a bit if you put a 4:3 device next to a 16:9 device.
You generally have two options for dealing with the aspect ratio: you can letterbox / pillarbox the output (which is fine for movies, but looks kinda lame for an app), or you can recognize that your output isn't always proportionately the same, and adjust the layout to fit nicely on the screen.
As far as size matching goes, when using a SurfaceView you can actually use a single size and then let the hardware scaler handle the rest. For an example of this, see the "Hardware scaler exerciser" in Grafika. I put a demo video here, though it's a bit hard to evaluate after getting rinsed through screenrecord + youtube. What you're seeing is the same couple of shapes rendered onto a Surface whose size has been set to an arbitrary value, and then scaled up to match the display. This is most obvious on the final setting, where it's drawing on a 106x64 surface.
With this, you could size your assets for 720p and always draw them the same way, and let the scaler deal with the stretching. See also this blog post.

Android game dev - use single view for everything?

So I'm trying to write a game for android, and I have a couple of questions regarding 'best practices' for android dev. The game I'm writing would have some dice on the top part of the screen, which the user should be able to drag around, and on the bottom half of the screen, I need to show a list of different numbers, updating as the dice are dropped into a new location. So, what's the best way to tackle this? I've coded up some sample code (which works) using a single view, and drawing the dice bitmaps and the numbers, but everything is so resolution-dependent that it bugs me. Would I gain anything by switching to an xml-defined view, and adding a dice view and a number-list view, and drawing those separately? Is there a standard or best practice that I should be following?
Thanks
It is a good practice to define a Layout in xml file so that your app runs on different screen sizes..
For more on why you should be using xml files, please refer to Android Design Guidelines.
When using xml file use dp for sizes and sp for text sizes, also use wrap_content and match_parent where ever possible.
You can also make density independent pixels in your code. Please see this..
public float typedDimension(int a){
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, (float) a,
getResources().getDisplayMetrics());
}
Firstly, SurfaceView is a good choice for game development - it will give you much better performance than a standard view.
Secondly, a nice technique I have seen used is to write to a standard size off-screen surface and then scale that bitmap to the size of the screen. When you have screens of different size, everything will still be in the correct place. Note you should scale down rather than scale up, so you might want to use different sized images (for mdpi, hdpi, xhdpi) to avoid using too much memory on lower devices.

Android and supporting multiple screens layouts

I'm finishing off an Android app, all that remains is to adapt the UI layouts and graphics for multiple devices. I need particular elements placed in particular positions on the screen.
The Android docs explain how the multiple screen resolutions and sizes are classified, and explain the resource tagging system.
For example, both WVGA800 (480x800) and WVGA854 (480x854) are classified as normal high density screens. To cater for these you're asked to create a folder called "layout" (already present for "normal") and "drawable-hdpi".
The problem is this does nothing to differentiate two devices of the same classification, even if you use "dp" units. How can you provide layouts/drawables for WGA800 and for WGA854 separately?
The ratios are sufficiently different that the user easily notices bad scaling, and this is exacerbated by my need for things like a score and timer to appear in a particular place against a background image.
The same problem applies to the pairs {WQVGA400 (240x400), WQVGA432 (240x432)} and {WVGA800 (480x800), WVGA854 (480x854)}. How can you provide layout/drawables for WQVA400 and for WQGA432?
I think you're on the road to hell.
Android runs on an enormous variety of devices, more every week, and many formats don't exist yet but will introduce new variables. So even if you succeed, one new device with a slightly different screen size, and your app will fail.
It's a mistake to design for Android using specific screen resolutions, and is similar to the issues you'd find if you forced all pages to be the exact same size on the web, it rarely works well (e.g. even a tidy fixed-width site will fail miserably on mobile devices).
Android has been designed to support all this variation, but if you try to get pixel-perfect absolute-positioned rendering on every screen size you are swimming against the tide. It is likely to be very painful, very time consuming and expensive, and likely to ultimately fail. Even if you succeed, how on earth will you test it on all these screen variants? It sounds like testing hell too.
I STRONGLY recommend you accept you cannot do everything as exactly as you need to, and instead look at how to use ways of rendering objects fluidly, relative to each other, so the app looks good in all the different variations, using the different layouts for each group of resolutions to improve the experience on different size screens.
YES, that's possible:
First you have to create a instance of the display-class.
After that you get the display's width and heigth.
Then you can check each resolution in a loop, by using the if operator and set the image you want.
Example:
ImageView iview=(ImageView)findViewById(R.id.imageView1);
//here are the Bitmaps optimized for each screen resolution
Bitmap[] bitmaps={BitmapFactory.decodeResource(getResources(), R.drawable.icwvga800),BitmapFactory.decodeResource(getResources(), R.drawable.icwvga854),(...)};
// In this list all supported screensizes are defined
int[][] possibleScreenSolutions={{480,800},{480,854},{240,400},{240,432},{480,800},{480,854}};
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int[] ScreenSolution={display.getWidth(),display.getHeight()};
// Compare the real screen solution with the all supported ones
for(int i=0;i<possibleScreenSolutions.length;i++){
if((ScreenSolution[0]==possibleScreenSolutions[i][0])&&(ScreenSolution[1]==possibleScreenSolutions[i][1])){
iview.setImageBitmap(bitmaps[i]);// set the image
}
}
I agree with Ollie C: It's too confusing to check all resolutions, but It's at least possible.
I've tested it allready: It works.
Further to the answer/comments elsewhere on this page, I'd like to post another answer to my own question drawing attention to the type of screen resources that can be introduced. I'm not convinced this is made clear in the Android docs, but so far as drawables are concerned you can add screen size tags to drawable files on top of the dpi tag.
For example, adding a folder called drawable-large-mdpi is valid and devices with large screens and medium resolution will pull resources from here if they can. Warning though, switching the order of the tags matters: declaring drawable-mdpi-large is an error.

Categories

Resources