I just got the new Nexus 7 which pulls images from the drawable-xhdpi folder because it is 1920x1200. The Nexus 10 also pulls from the drawable-xhdpi folder. The same image looks too big on the Nexus 7 as a result (too big by 150% to be exact). Is there any way to specify a resourse (drawable) folder to use for a specific device?
It sounds like I should not be trying to over-ride the default drawable buckets since there are so many screen sizes and it could hinder me when I attempt to support even more devices. So then what is the best way to handle this problem? The below images illustrates my problem exactly. The play button gets scaled down from the Nexus 10 to the new Nexus 7 while the bearded guy gets scaled up so that it remains as the same physical size on both devices. My images are currently doing what the bearded guy image is doing but I would like it to do what the play/connect buttons do which is scale down on the New Nexus 7.
(top image = New Nexus 7
bottom image = Nexus 10)
In order to keep using the drawable resource folders, I had to do the following to differentiate the Nexus 7 2013 and the Nexus 10 since they both would use the xhdpi folder by default:
For the Nexus 7 I ended up using: drawable-sw600dp-xhdpi
For the Nexus 10 I ended up using: drawable-sw720dp-xhdpi
I had 2 sets of assets scaled differently in each folder.
You can't set a drawable folder for a specific device, and it's also impractical, since there are too many devices out there (see here for example).
However, if you are unhappy with the way android choose the buckets of which file to use for each device configuration, you can use your own algorithm. there are 2 options to where to put the files in this case:
put the image files in res/drawable-nodpi (or res/raw) . for each image add a suffix/prefix to show which configuration it's used for.
put the image files in assets . this is a more flexible method, since you can even create sub folders and any file name you wish.
in both methods, you should also use your own image-sampling method , depending on your own rules.
You can use the following code to get the size and then scale the image to the required size based on the size of the display.
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenDensity = metrics.densityDpi;
Related
I need to create two different layout folders based on this http://www.samsung.com/global/microsite/galaxytabs/specs.html specifications.
But I've seen that the two devices has the same display resolution and only difference is the size of the screen.
Is there a way to distinguish the two res folder?
on Android you can specify smallest width on the resources. Examples:
layout-sw600dp/ < that's a 7" like the Nexus 7
layout-sw720dp/ < that's a 10" like the Nexus 10
so all you have to do is to find out what's the smallest width in DP for the 8.4 inches (probably something around 660dp) and create the resource folder for it.
You can run this app on the tab 8.4 to find out it's size: https://play.google.com/store/apps/details?id=nl.qbus.sizemeup
I am trying to wrap my head around the idea of scaling images which is all new to me. I finally understand for icon launcher you want something like 48x48 for mdpi and 72x72 for hdpi. For this, I have no problem using google's provided tool. I have an image I downloaded from the net that is 178x283 pixels, 96 dpi. When my (4inch 480x800hdpi) phone emulator views this, the image is pretty large, taking about half the screen. On my (10inch1280x800mdpi)phone, it looks smaller, actually the exact same as the original. This is not what I want right? how do I want the images to be scaled? do I want them the same size as the original, or smaller on a small phone and bigger on a big phone. I assume after this step I create the correct qualifiers and do the math done in this thread to resize the images ? Supporting multiple screens on Android. I forgot to mention what does android OS do automatically, because I figured if I have one image in drawable, then it will automatically make the smaller phone have a small image and the bigger phone have a big image, but that is not happening(given that I don't hard code values).
EDIT: decided to use this http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html
EDIT2: I have gotten the images and layouts how I want them now, but my 10 inch won't use the correct layout folder. I have this
layout
layout-land
layout-sw720dp
layout-sw720dp-land
it only works when i name them layout-xlarge, which is deprecated, what gives
edit:is it because sw qualifier is only for 3.3+ and I am targeting 2.3+?
Do you want the images to scale? Or do you want them to stay a particular size.
If you want them to scale, you can use something like this in your layout
android:adjustViewBounds="true"
Then set your size however you want with either layout_width or maxWidth (and length respectively).
Then scale how you want to:
android:scaleType="centerInside"
If the images are pixelated, then you need to add larger images for each screen size under your res folder.
Create a different layout for 10 inches tablet and another for 7 inches tablet then use this code below:
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
final int height = dm.heightPixels;
final int width = dm.widthPixels;
if ((height == 1280) && (width == 800)) {
setContentView(R.layout.10inchLayout);
}else if ((heig
ht == 1024) && (width == 600)) {
setContentView(R.layout.7inchLayout);
}
else {
setContentView(R.layout.PhoneinchLayout);
}
Hope it helps you.
I know that the title makes it sound like it is a duplicate, but I think I have a very specific situation here that I can't solve from all of my searches.
First, I have images that are specifically sized based off of a specific monitor (Yes, monitor. Not handheld device's screen). The images are based off of these specific settings:
1600x900 20" monitor at 96ppi
Now, all of the images must be sized in millimeters (they are square images btw, so Height=Width). Using these specific settings as a determining factor, 1mm = 3.78px. So, my images are sized using this. For example, for an image to appear as 65mm, I size the images to 246px. I tested this in Photoshop using these settings, and measuring the image on the screen did in fact come out correct.
So now in my Android application, I load up these images into ImageViews to be displayed. This is where I am stuck. The device is an MDPI device. If I load the images into the MDPI drawables folder, the images appear too large on the monitor. Using my above example, I convert the Drawable to a Bitmap and dump the Height of the image to my log. This is correct and shows 246px, but for some reason it is measuring well over 85mm instead of 65mm.
If I load all of my images into the HDPI (yes, I know it is an mdpi device so it will be sized by the Android OS), the height of the image (using my example) dumps as 164px and appears at roughly 50mm. This is more explainable, but still I am still confused on how to get these images to appear as they did in Photoshop.
So my question is, what is the best way to programmatically size the ImageView to be the exact size of the image? For my example, I need to find out why my 246px square image (at 96ppi) is not showing up as 65mm like it should.
Because these ImageViews are generated programmatically, I have tried the following two things:
Set the ImageView Height and Width (using LayoutParams) to the height of the image (246px). I did this thinking WRAP_CONTENT was not acting as it should.
Used ImageView.ScaleType.CENTER to try and make sure the ImageView is sized exactly to the image.
Neither of these things seem to have effected the output.
UPDATES:
I have verified that my device is a MDPI device. This means that there is not DPI to PX conversion (or vice versa) necessary because of the 1:1 relationship. Somewhere, the sizes are being increased and I cannot determine where. As I indicated in the comments for the answer below, when I pull my Drawable and convert it to Bitmap, it pulls the EXACT pixel Height that I made it. I am starting to figure out the percentage of size difference from what it should be (65mm vs 85mm) and it works out to be 23.529%. I am scaling my bitmaps subtracting this value, but it ruins the quality of my image.
I am beginning to give up.
The device I am utilizing is an MK802III Rockchip Device (Amazon Link)
Android modifies all images for display with the following formula:
px = dp * (dpi / 160)
Where "dpi" is the screen density in dots-per-inch of a device's display.
Additionally, Android looks through a hierarchy of drawable folders when deciding which image to display. As we all know, an HDPI device will use an image from the drawale-hdpi folder while an MDPI device will display the same named image from the drawable-mdpi directory.
However, when an MDPI device cannot find an image in the drawable-mdpi directory, it will eventually choose from the drawable-hdpi folder, but it will down-scale the image for display on the MDPI screen.
This explains why your image appears smaller when you saved it in the drawable-hdpi folder.
But, it does not explain why the image appears too large when correctly placed in the drawable-mdpi folder.
It so happens that:
65mm ~= 85mm * (120 / 160)
50mm ~= 85mm * (120 / 240)
This is the scaling that I would expect for your images if your device were LDPI (120dpi) instead of MDPI (160dpi) as reported.
I hate answering my own question, but I am just going to update everyone what I did. If someone comes up with a better solution, I am all ears. I had to force this along because I am on a tight deadline.
I created a dummy application that dumped boxes that I could measure. Using these, I determined that 1 millimeter is 3 density pixels. Let me repeat that, 1mm = 3dp.
Using this value, I resized all of my images (utilizing a PHP script) to this constraint. All of my images are appearing as normal. 195dp = 65mm, and it appears as such.
Like I said, any explanation as to why I had to do this and you get an upvote and answer.
I am very confuse now for set layout and drawable folder. I want that my graphics support both Galaxy nexus 7 asus and Galaxy tab. I prepare a demo app first and what I saw both support hdpi folder with normal layout. But both have different resolution and density. so my graphics not good look in Galaxy tab. I search and find so many links and go through that but not working for me. Don't know what mistake i do. Please correct me or give me any suggestions.
Preferred link: galaxy tab 7 vs nexus 7 different dimensions res folder
Layout folders for Google Nexus 7 and 10
The Nexus7 is a unique device, with a somewhat strange dpi structure.
For more than you probably need to know, here is a very good explanation (from Dianne Hackborn - an Android engineer at Google): Dianne Hackborn explains the unique resolution of the Nexus7
The Nexus7 will use resources out of the xhdpi folder - and scale them for it's unique resolution.
This is the first time this has been done, so is definitely unique (and explains why you might be seeing strange behavior).
There may be two possible solutions.
1. First is you can use a new folder for the layout of the galaxy tab named layout-sw600dp and keep your layout xml file with new layout for galaxy tab.refer this link.
res/layout-sw600dp/main_activity.xml # For 7” tablets (600dp wide and bigger)
2. The second solution may be that you manually find out the resolutions of the mobile and set the drawables for the resolution manually.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int scrheight = metrics.heightPixels;
int scrwidth = metrics.widthPixels;
if(scrheight==1024 && scrwidth==600)
{
**set ur resources here**
}
In my android app, I want to support multiple screen sizes. I realize that for Android "large" means a lot of the current phone screens at 480 x 800 pixels as well as a 7" tablet like the Nexus 7 which has 800 x 1280 pixels. But I'd like to create 2 separate layouts for those two display sizes. I've found that rather than using res/layout-large, using res/layout-h800dp gives me greater control of which size screen uses what layout. (I'm using a portrait orientation, hence h800dp) The problem I'm having is this: sometimes the h800dp layout uses the images in the drawable-mdpi folder, and sometimes it uses the images in the drawable-hdpi folder. I'm using the same syntax in the xml to call the images: `android:src="#drawable/image", but in one activity it looks in the mdpi drawable folder, and in the next activity, it looks in the ldpi drawable folder. Is there any way to get the h800dp layouts to always look in the ldpi folder?
This link explains nearly everything regarding screen properties (DPI, physical size, resolution, etc.)
What you may be able to do is specify folders like layout-large-hdpi, layout-large-mdpi, and layout-large-ldpi.
Experiment with blending these types together in folder names.