If you put drawables in /drawables directory they will be scaled and if you want specific drawables for different densities you need to put them in specific directory (/drawables-hdpi, /drawables-mdpi etc.)
But if I have drawables only in /drawable-tvdpi will they scale down/up automaticly for ither densities?
Yes they'll scale, so if you put a 133 x 133px drawable in the tvdpi folder, it'll be 100px on mdpi, 150px for hdpi, and so on.
There's more information on the Android Developers - Screen Support page, but in general you can get away with just putting drawables in the tvdpi folder.
I believe they will, Android always picks the best available image inside your directories, i.e. if you have an mdpi phone, and two resource types, hdpi and xhdpi, it will try to pick the one immediately above the requested density (hdpi) instead of the bigger one, because it correctly assumes it' going to be enough. Take a look here.
However why not try it for yourself using Bluestacks? It's an Android simulator that runs pretty well. It's still in beta, but has served me well.
Related
As a general rule, when storing image resources for use in an Android project, should they be placed in the res/drawable or the res/mipmap folder?
Apologies for the simple question, I'm relatively new to Android development. The IDE I'm using is Android Studio 1.0.
My rule is that if an image will have noticeable changes in quality when they are scaled up or down depending on the android device should be stored in mipmap folders. Examples of such images would be icons, slider bar scrubbers or custom google map markers. Images that don't get affected by changes in scale can be put in the drawable res folder.
The graphic resources are stored in corresponding folders “drawable”. A store application icons are stored in the folders “mipmap”. To make the icon you have to make the files with the identical name which will be differ by resolution only and will be placed in the correspondent folders “mipmap”. Here are the the dimensions in pixels for each screen density:
LDPI 36×36.
MDPI 48×48.
TVDPI 64×64.
HDPI 72×72.
XHDPI 96×96.
XXHDPI 144×144.
XXXHDPI 192×192.
When the screen density is not important, I create a simple “drawable” folder and I store there all images. If the screen density is important it is possible to calculate the dimensions of the image, based on the ratio of the size of the base image to the appropriate screen ratio. For the base density is taken MDPI (48 × 48):
LDPI — MDPIx0.75.
HDPI — MDPIx1.5.
TVDPI — MDPIx1.33.
XHDPI — MDPIx2.
XXHDPI — MDPIx3.
XXXHDPI — MDPIx4.
At the time of publication in the convenience store (play.google.com), you will need also 512 × 512 icon and picture for advertisment of 1024 × 500.
In the manifest, do not forget to register R.mipmap.your_icon_name (default R.mipmap.ic_launcher) and the system will automatically select the icon under the screen density
Images that don't get affected by changes in scale can be put in the drawable folder.
If you are building different versions of your app for different densities, you should know about the “mipmap” resource directory. This is exactly like “drawable” resources, except it does not participate in density stripping when creating different apk targets.
Provide at least an xxxhdpi app icon because devices can display large app icons on the launcher.
It’s best practice to place your app icons in mipmap- folders (not the drawable- folders) because they are used at resolutions different from the device’s current density.
I have all of the dpi drawable directories (are xxhdpi and xxxhdpi even necessary?) consisting of nine-patch bitmaps, the drawable resource file in the drawable directory that retrieves all of the scaled bitmaps, and I set the backgrounds of the Buttons with the drawable resource file... Now, my problem is that I also created "scaled" layout directories in terms of size (small, normal, and etc.), in which I tried to manually change the dp of the buttons as follows:
Here's my xhdpi bitmap:
... But it appears like this on the Nexus 7 virtual emulator (7.0", 1200X1920: xhdpi) in the layout-large directory:
... And when I manually change the dp size to 200 of one of the buttons:
^^^ How do my directories look by the way? ... And why does the button appear like that? ^^^
All of that said, I just don't understand why we need density-based drawable directories (mdpi, hdpi, xhdpi, and etc.) as well as layout resource directories, when we could just simply modify the dp of images in each unique layout regarding the screen's size (small, normal, and etc.).
#dpark14 I basically already answered the question you asked in a your post from yesterday here: Is modifying the dp size as opposed to pixels recommended for various screen sizes?
Perhaps you should have edited your last question to include the code and images above so it could be consolidated.
As I said in my answer (and one of the other comments said):
It is entirely up to you if you want to change the layout width and height (in dp) of an imageButton. There is certainly nothing wrong with setting width and height of an imageButton or any UI element for that matter, in each unique layout resource file for various screens. Did you have specific code you wanted to get feedback about?
Now that you have included some images I can see some of what you have.
You should really take a look at this:
Android Studio drawable folders
And it would benefit you to read through the Android documentation again:
http://developer.android.com/guide/practices/screens_support.html
To summarize a few general ideas:
You don't need a default drawable folder, but you should have the following:
drawable-mdpi (medium) ~160dpi
drawable-hdpi (high) ~240dpi
drawable-xhdpi (extra-high) ~320dpi
drawable-xxhdpi (extra-extra-high) ~480dpi
drawable-xxxhdpi (extra-extra-extra-high) ~640dpi
As the Android documentation says in the link above:
Your application achieves "density independence" when it preserves the physical size (from the user's point of view) of user interface elements when displayed on screens with different densities.
Instead of:
If, for some reason (as it looks like you're having issues with) you've achieved density independence, but your image doesn't fit well, that's when you can start to step in with changes to w/h and res/layout
Also from my previous answer:
As you alluded to: you could create different res/dimens directories for various devices based on "minimums" e.g. w800dp/dimens.xml and then create elements in that specific dimens.xml e.g. values-w411/dimens.xml for width and height that correspond with your images that aren't fitting well when you test your app.
As a first step, perhaps you should try it out. Yes, this takes time, but try a stand-alone test separate from your app first. Just add one image (perhaps the one you are having issues with). See what happens when you load it into different Nexus devices in the emulator. Does the image achieve "density independence" i.e. preserves the physical size across devices? If it does, and there's an issue with its w/h in relation to the confines of a specific device, as I said in my previous answer and now here, create a dimens directory (within a values-... directory) specifically for the problem device and change the layout_width/layout_height for that specific image or view.
For more on specific device w/h: https://design.google.com/devices/
Last two questions stayed unanswered, I hope "third one's the charm" works :)
I want application that is HDPI use those drawables in folder "drawable-xhdpi" and LDPI devices those in "drawable-mdpi". So I don't have to duplicate same images. Is this possible?
Yes, Android scales drawables, selecting the drawable that will produce the best result. But not all scaling combinations work that well. Downscaling to MDPI can produce noticeably poor results. XHDPI to HDPI generally produces pretty good results. But given that the overwhelming majority of devices these days are HDPI, it's probably worthwhile to have HDPI resources. HDPI to XHDPI scaling is not terrible. Some 1280x720 devices uses XHDPI resource. These generally look ok. Google TV uses XHDPI as well. On a huge screen, scaling errors are visible.
LDPI devices are -- for all practical purposes -- non-existent now.
True that generating scaled resources is an enormous PITA. But, in my opinion, you really need to do MDPI and HDPI. And once you've got that unpleasant workflow down, it doesn't require a lot of extra work to generate XHDPI. For what it's worth, if your artwork is in vector format, the vast majority of resources don't need tweaking for specific resolutions. There doesn't seem to be any compelling need to pixel-align edges of square objects, for example. Usually it's only interior features in complex icons and artwork that benefit from some amount of pixel-pushing.
It's pretty clear that XHDPI is going to be come more and more common. Trust me, you don't want to go back and re-do all your artwork in XHDPI after the fact. My advice: if you intend to still be shipping your app a year from now, suck it up, and do the nasty as you go, while it's still relatively easy.
In my experience, if you place an image in just some of the drawable folders, but not all, the OS will choose the "best" image for the device that you are using, even if it is not exactly the perfect fit. For example, if you put an image called arrow.png ONLY in the drawable-hdpi folder, all devices will use that image for the arrow drawable, and scale it down or up appropriately, stretching or shrinking the image.
That being said, you should be able to accomplish what you want by simply putting your image in the right folders and allowing the devices to choose the correct one. For example, if you were trying to accomplish your task with only one image, arrow.png:
drawable-xhdpi/ -> arrow.png
drawable-hdpi/ -> empty
drawable-mdpi/ -> arrow.png
drawable-ldpi/ -> empty
drawable/ -> empty
If you use the app on an ldpi device, the device will use the mdpi image, as you wanted, because it is closest to the correct resolution. On the hdpi phone, it will use the xhdpi image, because it is again the closest to the correct resolution.
Yes. Android automatically downscales/upscales resources that it cannot find. If you were to only put resources in the XHDPI folder it would just work, Android would take care of resizing them to work in all the other densities.
We should add this code in MainActivity class and copy image to dhpi folder with ic_launcher, ic_launcher2, ic_launcher3 and ic_1 is image name, we can change size: width and height
int array_image[]={R.drawable.ic_launcher,
R.drawable.ic_launcher2,
R.drawable.ic_launcher3,
R.drawable.ic_1
}
I have a quick question: will it work when I put the same 57px x 57px icon to all drawable-ldpi, drawable-mdpi and drawable-hdpi folders. Will it run on all devices?
in other words if small icon will be visible on big screens or x-large screens.
It will work, but you really should not use size of 57x57 for any screen size - scaled down images will look as ugly as scaled up. Better avoid it.
Please read more here: http://developer.android.com/guide/practices/ui_guidelines/icon_design_launcher.html (yes, it is an official documentation).
Yes, it'll work. But it is good to have all icons. Because it'll be pixelat on large screens.
If you simple put icon in drawalbe folder (which is default folder) and you don't have any other folders like hdpi, mdpi, ldpi for all screen sizes. then it'll also be considered for all resolutions/sizes.
It will work. But it will not look well on some screen.
I'm currently looking into getting my android app to work on Kindle Fire. I've got artwork for both MDPI and HDPI screens, but I noticed that when I load the app up on the Kindle, it displays the MDPI artwork and stretches some of my artwork that I'm filling parent with a little more than I want.
I was wondering if there's any way on Android to under certain circumstances (like if I'm on a Kindle), force it to load from the HDPI artwork, instead of defaulting to MDPI.
I do realize that I could just save my HDPI artwork in the MDPI folder with a slightly different name and do a check for every resource, but that's a lot of overhead, not to mention an increase in the size of my app, which I'd also like to avoid.
Thanks
Update: Still looking at this one. I guess what I'm really getting at, is there a way for an android device to chose HDPI artwork instead of MDPI, even though the MDPI artwork exists?
The Kindle Fire is 1024x600 with 160 dpi, right?
You can try new resourses with that resolution. And place them in the MDPI folder.
Add layout-large at /res directory and copy your layout file there.
That way, with the Kindle Fire, you use the layout at layout-large pointing to bigger resources in the MDPI folder.
And make sure you always use nine-patch drawables for resources.
Hope this helps you.
Ended up using a hack solution in the meantime, but I came across this:
I don't want Android to resize my bitmap Automatically
Pretty much just needed to move my hdpi images into the nodpi folder (in order to avoid the scaling issues) and changed the names slightly (I added a _hd to the name). After that I made an image loader that takes in the name of the image I want and returns _hd images if device is hdpi or if it's kindle fire:
id = ctx.getResources().getIdentifier(string + "_hd", "drawable", context.getPackageName());
Note: The docs do discourage the use of getIdentifier(), as it is less efficient than just using the resource address, but I took a look at the load times and loading 1000 images with getIdentifier takes .25 seconds, which is fine with me especially since I'm not loading anywhere close to that many images.
You can try new resources with that resolution and place them in the MDPI folder. Add layout-large at /res directory and copy your layout file there. That way, with the Kindle Fire, you use the layout at layout-large pointing to bigger resources in the MDPI folder.