I am new to android but an experienced Java and other languages programmer.
I need to create a custom background for the initial app activity. It's quite simple, here it is:
http://imgur.com/VrtrRo5
Should be pretty simple!
The best I could come up with is:
android:background="#drawable/background"
First, this was driving me crazy, I was always getting:
Binary XML file line #1: Error inflating class <unknown>
Searching, first hints pointed to a size issue - but the file size is 11kB! Then I found more hits and they essentially pointed to resolution. My image dimensions were 1080x1920px. I resized it to 768px (keeping ratio) and - voilá! - now it loaded.
However, I wonder if this is the correct approach. After many years of web development, I wonder if a "css-like" approach would be more suitable. If I use that image size, will it work fine for all devices and all resolutions? After all, it's just two colors (granted, with a curved element).
What are best practices for such cases? Thanks!
See this:
https://developer.android.com/training/basics/supporting-devices/screens.html
You should create diferent bitmaps for diferent resolution and screen density.
The best practices for this come in understanding the following 3 parts of application development and design: how to handle bitmaps, how to provide resources, and who is the target for your app.
Starting at who is the target of your app is not just the person but the devices they tend to use and the devices you want to support. In your question you mentioned that resizing the image to 768px prevented the error from occurring but that error happened because 1080 (at 16:9) resolution are rather large images when decompressed. So your own development device is not capable of handling a rather large image. Which is 8M when decompressed as ARGB, the 768px image is just above 4MB. So you can see that there is a significant memory difference. In addition to considering memory sizes you may consider screen size differences, image for a moment if you had a 800x480 image being displayed on a very capable 2048x1536 display, not considering memory usage a scaled image would look very jagged and the aspect ratio would be flawed, even worse would be if the device's orientation changed.
The conclusion is to provide the graphics for the kind of devices you want to support. Providing these resources is a matter of understanding how apps organize their resources.
Related
Regarding Android's call to provide multiple versions of a bitmap/image, why can't only the highest resolution image be used?
E.g if the xxhdpi image is available - will that be able to scale down to all lower density versions or will it just mean it will scale bigger than the allocated size (View)?
PS: If I'm using a background image, does scaling matter? E.g. should I still provide multiple versions of 1 image to fit different pixel densities?
Usually image scaling operation is resourceful and the outcome might be worse than using pre-scaled image.
It has already been answered several times, but I will answer it again. Btw I'm not myself a big pro in Android, but I will try to answer in the best way possible.
Automatic scaling is a thing in Android, but using that is a waste of resource, we already know that using a PNG Graphic asset is a waste of CPU/GPU power when we can use XML for basic designs (which uses less resources), so why waste more power for downscaling it (which increases app opening time and makes it laggy), simply creating multiple sized images for different display sizes is the best option.
A simple and convenient option is to use a free software like Adobe XD which supports export into different sizes.
Simple answer: Avoid using PNG(or other image format), but when you don't have other options do create multiple sizes to save resources.
I have designed an in-app keypad for my Android application and I need to provide an image for every key. Currently I've only loaded one large image for each one that is being scaled down to adjust to the layout. Also, this looks nice in every resolution.
Is this approach acceptable or should I provide different images for different screen densities? Currently I've placed those inside the generic drawable directory.
You should. Some mobiles with lower resolution, usually won't have much memory. Loading large images in small screen takes too much memory, which might end up crashing. So if you give different images, then according to density it will take appropriate images. check this out.
It's acceptable in some cases but certainly not optimal.
For best memory performance and the least amount of artifacts I would still recommend to provide alternative bitmap resources for different densities, like the Android documentation recommends.
i am NOT an android developer and im trying to understand what they need in terms of graphical resources to make an app that functions across many android devices.
i have (tried to) read this page http://developer.android.com/guide/practices/screens_support.html , but find it somewhat bewildering. they talk as if screen density is the important thing "Supply alternative bitmap drawables for different screen densities" but then, if you dont know the size of the screen, you cant really think in terms of layout. is the idea to make buttons and logos that are the same size on all screens with the same density, such that on a large screen there is just a bunch of space, and on the small screen its all packed in tight? i dont understand how just thinking in pixel density gets me any closer to knowing what to provide.
are you supposed to create resources for every screen size AND pixel density? say it aint so.
anyway can somebody tell me... if you were developing an app what do you need for graphics? is it possible to provide graphics that are large and just let them scale down? is it inevitable that the devloper will have to mess with the graphics himself anyway? or can he be provided with sets of png files of certain sizes that will be ready to use?
thanks!
Here's what we do at my work place. Suppose we get a desing for the app. We make our designer create 3 psds versions for the same desing. the 3 psd's are for the 3 ranges of desnity. The size used for the psd are
240*320 (Low Density)
320*480 (Medium Density)
480*800 (High Density)
Most of the time when I write layouts, I use wrap_content which means a view must take the size of the content it wraps. Which works most of the time as I have a density specific version of the design so the image i use as background should be suitable. The thing to note is that, in android you can can put the 3 sizes of the same image in different folders such as drawable/ldpi, drawable/hdpi.
Eg: you have a bg.png and have a version for large phones and a version for small phones. You put the big bg.png into hdpi folder and the small png in the ldpi folder. Android will automatically select the appropriate image based on the phone density. But you need to make sure the file name is the same.
There are cases where you need to resize you background images without makeing the image looking too scaled. For this android uses the draw9patch tool. With this tool you can specify areas which can scale and areas that shouldn't scale.
9 Patch png's are your friend. Read up on them here:
http://developer.android.com/guide/topics/resources/drawable-resource.html#NinePatch
and here:
http://developer.android.com/guide/developing/tools/draw9patch.html
Those are your best bet for any kind of graphic that will stretch nicely (i.e. not gradients, they will come out slightly pixelated on some screens probably) The power of these types of images is that you can tell the system which pixels to repeat if it needs to stretch the graphic. This means that stretching can be done without loss of image quality (again depending on your image and how you choose to make the nine patch. The "show bad patches" button in the draw9patch program will show you potential problems. Hint: keep your repeatable pixels down to 1 on left and 1 on top and you'll have no problems with bad patches) Any graphics that can be made in to 9 patches will only need 1 size since the system can effectively make it whatever size it needs.
are you supposed to create resources for every screen size AND pixel density?
You may if you like. This would ensure that the application will look great across all devices. I understand that this is not feasible for all projects though. In general if you make separate resources for the different densities you'll get something that looks acceptable on most of the devices out there. All of the devices are classified as ldpi, mdpi, or hdpi (there may be an "extra high" level now too, I am not certain off the top of my head) So if you supply graphics for those 3 densities then the system will know where the device falls under and will pull the correct graphics.
is it possible to provide graphics that are large and just let them scale down?
Yes the system will scale down your graphics if needbe. But be aware there are consequences with this approach. First every time the system hast to scale a graphic up or down it is going to taking up CPU and memory to do so. This may not be an issue if you have relatively few things to scale, but if you have many it could cause noticeable lag time during on the lower power phones. Second, To my knowledge all of the graphics in android are raster, which means if you are letting the system scale something up or down image quality is going to decrease some. Again depending on the specific images this may be more or less noticeable on the actually device at runtime.
My best advice is supply them with resources of a few different sizes and run the app on as many different devices as you can. Once you see how your different resources look on the devices of different sizes you'll have a much better feel for which ones you need to supply to get the UI looking as consistent as possible across the largest swath of screen sizes and densities.
I've been through this post (and others) as well as through the documentation about supporting different screen resolutions in Android, but I couldn't find a clear answer to a (simple) question:
Is it ok to just use "res/drawable" for images in an android app?
Background: The only images that are needed in this specific app are the app icon itself and an icon for a notification, there won't be any images in any layout.So in my understanding, if no "hdpi"-, "mdpi"- and "ldpi"-folders are found, Android will use "res/drawable" as the fallback.As the only pitfall with different screen-resolution seems to be that Android will scale images for a specific resolution if no special one is found, this should only be a problem when UPscaling, because the image will get blurry. But if I provide all "hdpi"-images in "res/drawable" (instead of 3 different ones), won't Android just DOWNscale those images if the size is too big?If that's true, I could save some APK-space by just a third of the images.
Follow-Up question: I read that for API-level 3 a dir by the name "drawable-v3" is required. Is that true or is "drawable" the fallback for this API-level also?
Any hint is appreciated.
The images in the drawables folder are assumed to be at mdpi resolution, so they will get scaled up/down if you don't provide the others.
Scaled up images will be low-resolution and look fuzzy. Scaled down images will have pixels missing and look jaggy.
So your app will "work" with only one set of default images, but will look awful on many devices. I strongly advise that you create the images in different sizes, so it looks great on all devices - it's a bit boring, but not hard to do.
It won't be long before we have xhdpi devices, so while you're at it you may want to create those too.
I assume you've read this
Not a complete answer, but: highly downscaled images can and usually do look just as bad as upscaled images (but in a different way), because graphics libraries almost exclusively use interpolation methods for resizing, and interpolation methods are limited in terms of how much they can shrink an image before serious information loss (to about 50% for linear methods and down to about 25% for bicubic methods). This is why most platforms have evolved conventions (like hdpi, mdpi etc.) that let you embed images that are best for each screen size.
I use drawable/ all the time, and then I go to BestBuy and all the local wireless stores and test my apps on small/large/huge(tablet) devices and they look just fine.
Unless you have some reason to target pre-Donut devices (now only 4% of the devices according to http://developer.android.com/resources/dashboard/platform-versions.html), then you should put your bitmaps in one of the -Xdpi directories. The generic "drawable" directory is a synonym of "drawable-mdpi" for compatibility reasons, but a modern well-written app should be putting its drawables in a directory matching the density they are designed for.
res/drawable is the fallback
the caveat is that scaling not only degrades the image but takes processing time too.
I have not even read the API-Level 3 docs yet, sorry for 1/2 an answer
For what it is worth I found the image handling of Android to be tedious and unreliable. The concept of including different size images for different screens will result in large application files bloated with images. There are already screens that don't fit in the standard resolution ranges. I have found it is best not to let android handle the scaling, it seems to create a base image for the smallest screen you target and then scale it up resulting in ordinary looking images on large screens. This happens even if you made the image specifically for the large screen.
My solution that seems to work on everything from a 2" samsung phone to a Sony Tablet is to create images at high resolution and use Bitmap.createScaledBitmap() to get the size I need.
caveat: I am new to Android and have lots to learn.
My android app will work for both normal and hdpi device. I don't want to create two sets of images assets for normal and hdpi screen.
So, could I just create image assets for hdpi only, and use them for both normal and hdpi device. Of course, the hdpi images will be auto scaled to fit normal screen devices. Is it OK? How much performance overhead will be caused by auto scaling hdpi images to fit normal screens?
Thanks.
The answer is "it depends".
If you are filling a listview of 10,000 items with images, then there will be a major performance difference.
If you are running a game engine with even fairly simple graphics, then there will be a major performance difference.
If you are making a custom button background scale, don't worry about it.
As far as simple UI's go, providing multiple resources makes it look better but doesn't really affect performance.
The real performance concern is with sprite scaling in games and other high framerate applications.
None. Do the scaling once at startup and keep the scaled image in memory.
You can generate performance statistics using android.os.Debug class
Start tracing by executing Debug.startMethodTracing() and stop it with Debug.stopMethodTracing(). File with the trace will be created on sd card.
Then you can analyze it using TraceView tool.
This should answer you how big is performance overhead of image scaling in your application.
In your position I would generate hdpi set of images and add it to the project.