I have a device with resolution 800*480.
I create "Hello word" application. Then I get DisplayMetrics in onCreate of MainActivity.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Log.d("Resolution", "resolution: " + metrics.widthPixels + " x " + metrics.heightPixels);
In DisplayMetrics there are 533*320 pixels. Why?
How can I make application for resolution 800*480 pixels.
It's because you are reading device independent pixels not real pixels. These dip are equal to mdpi resolution. So despite real screen size, you should check what density it is (mdpi or hdpi or xdpi) and then put your hi-res assets in -hdpi suffixed folder (i.e. drawable-hdpi or layout-hdpi). Usually you set your layout in dp (so one layout XML file per activity usually suffices, and you should put them as usual in generic res/layout folder). and then put hi res drawables to make app look nicer on hdpi device
See this article for pixel-size and density relations...
Related
I will get 5 different images from server that will be in xxxhdpi, xxhdpi, xhdpi, hdpi, mdpi.
The URL will be something like this.
http://www.abctest.com/image-xxxhdpi.jpg
http://www.abctest.com/image-hdpi.jpg
Is there any way i can put these images in drawable folder. So that each device will pickup the image according to its density. I googled but unable to find any way to achieve this.
Or If go to different approach, and get 1 large image from server, then on smaller devices it will create lagging.
Is there any way i can put these images in drawable folder.
Not at runtime. Resources and assets are read-only at runtime.
You can check density of the device by this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenDensity = metrics.densityDpi;
and choose image based on the density.
Edited
or you can also do this :
float density = getResources().getDisplayMetrics().density;
// return 0.75 if it's LDPI
// return 1.0 if it's MDPI
// return 1.5 if it's HDPI
// return 2.0 if it's XHDPI
// return 3.0 if it's XXHDPI
// return 4.0 if it's XXXHDPI
Is it possible to use common hdpi folder for all screen densities? I have quite a lot images. If I make specific copies to folders drawable-hdpi, drawable-ldpi, drawable-xhdpi, ... but it takes huge data (backgrounds, bitmaps).
Is it possible to set only one drawable folder for all devices and then rescale according to a specific device programmatically?
I think about this code to get display size of the scree:
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
Then I will get display density of the device, something like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
density = metrics.density; // 1 - 1,5 - 2 .....
The I will recalculate size of imageview with density:
ImageView logo = (ImageView)findViewById(R.id.logo);
LinearLayout.LayoutParams logo1 = (LinearLayout.LayoutParams) logo.getLayoutParams();
logo1.width = (int)(logo.getWidth()*density);
logo1.height = (int)(logo.getHeight()*density);
logo1.leftMargin=(int)(logo1.leftMargin*density); // for margin
logo1.topMargin=(int)(logo1.topMargin*density); // for margin
logo1.rightMargin=(int)(logo1.rightMargin*density); // for margin
logo1.bottomMargin=(int)(logo1.bottomMargin*density); // for margin
My main problem is I need to have all proportions of graphic same on all devices. It means I must recalculate imageViews accroding to the screen size.
Is this a right way to get density independent screen? How does android work on other devices if only hdpi folder contains files. Does it take files from this folder? Can I set one common drawable folder to all densities?
I would strongly (strongly) advise against doing this. However, if you want the system to rescale your image assets, design them for mdpi (the baseline density) and put them in drawable/.
That said, you need at least mdpi and hdpi to get reasonable scaling (since hdpi is 1.5x mdpi, scaling algorithms produce worse results than for the other conversions from mdpi).
Make sure you've read and understood Providing Resources and Supporting Multiple Screens before you start dealing with resources.
P.S. The layout solution is wrong for a few reasons (e.g., setting margins instead of size) but it's also the completely wrong thing to do. Don't do it!
I want to know in my code whether my device uses 320-hdpi or 320-mdpi resources. Is it possible?
I gone through some examples like this but it gives me generic density pixels (like mdpi, ldpi and hdpi). But I want to know exactly which resource data is used by my device. Whether it is 320-hdpi, 320-mdpi or 320-ldpi.
Thank you in advance.
I think you can use DisplayMetrics class for this.
Use following code to get display metrics.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Then you can obtain desity by metrics.desity
If the density is 1 than mdpi resources will be use.
If its less than 1 then ldpi resources will be used.
If its 1.5 than hdpi resources will be used.
If its 2 than xhdpi resources will be used.
From your Activity try...
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
You can then look at the various fields of metrics to find out physical and dpi characteristics of the display.
See DisplayMetrics documentation.
You can install this app on your device
https://play.google.com/store/apps/details?id=com.roysolberg.android.developertools
Go to "Resource Qualifiers", it will give you all information such as your device screen size (normal, large, xlarge) and screen density (ldpi, mdpi, hdpi,...)
How can I put different resources for different dpi on ICS with the same sw800dp smallest width?
Details: There are two tablets with ICS 4.0.4. First one has 1280x800 resolution and mdpi (160) density. Second one has 1920x1200 resolution and hdpi (240) density. So in terms of smallest width they both have the same sw800dp qualifier but different mdpi/hdpi density qualifiers.
I need to have different layouts and images for these two resolutions.
So I created two directories:
layout-sw800dp-mdpi
layout-sw800dp-hdpi
I thought that each device will choose its own directory according to the smallest width AND density.
BUT both of them take resources from the same sw800dp-hdpi folder!
I'm very confused and do not know how to separate resources for that two different resolutions.
Any help is really appreciated.
Thanks in advance.
You should use the same layout, located in /layout/sw800dp, and create /drawable-mdpi , /drawable-hdpi to put your custom drawables, the system will apply the correct ones to each device, using the same layout. Those devices should have similar size and aspect...
Use this to get the density:
float density = getBaseContext().getResources().getDisplayMetrics().density;
Screen height:
int h = 0;
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
h = (int) display.getHeight();
Screen width:
int w = 0;
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
w = (int) display.getWidth()
After that just select the correct resources.
I need drawable resources for different resolutions, such as 320x480, 800x480, 854x480, 800x600
1024x600, 1024x768, 1024x800. It is a game and the scaling of bitmaps is inacceptable, coz they are very sensitive to it. dpi dependent folders and combination with screen sizes(which are deprecated but no other way to set drawable for large screens with same resolution and differend dpi) are not enaugh. How to distinguish graphics for 1024x600 and 1024x768 for example?
It is so sad to stop use mechanism of auto picking resources and switching to manual loading from assets.
any ideas?
I'm usually using 4 resource folders for drawables:
drawable-mdpi for 320x480
drawable-hdpi for 480x800 and 480x854
drawable-large-hdpi for 600x1024, 768x1024 and so on
drawable-xlarge-mdpi for 800x1280
These are just enough in my mind. Also, you don't need to worry about different drawable resources for, in example, devices with 800x480 and 854x480 screen sizes: you can specify an offset on the edges of your screen equal to 27 pixels and center your game on the screen. Hope this helps.
If you want a pixel perfect fit you could always load the background at runtime via a simple method:
private void setBackgroundImage() {
DisplayMetrics dm = getResources().getDisplayMetrics();
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
// TODO: Conditional Structure to apply the right drawable
// ressource to be applied in the background
}
After you've acquired the resolution of the display you can apply the appropriate background via the setBackgroundDrawable method.