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
Related
I am having trouble configuring my Android application for another screen density. Currently, my app runs on HDPI (1.5) screens and I am trying to get the dimensions of my pngs and my values in my dimension.xml to be compatible with XHDPI (2.0) screens.
For example, my background png is currently 1280px x 800px and it works well with my HDPI (1.5) screen. I assumed this would mean that I would need a 1280 * (4/3) = 1706.67px by 800 * (4/3) = 1066.67px dimension png. This did not show the same as my current tablet.
Also, my screens are almost exactly the same size
LDPI = 0.75x
MDPI = ORIGINAL
HDPI = 1.5x
If you have an image 1000X1000 (pixels) you have to create the following versions of the image:
LDPI = 750x750
LMDPI = 1000X1000 (THE ORIGINAL IMAGE SIZE)
MDPI = 1500X15000
Except, in #dimension, HAS NOT put some values "dp" or "sp" and then used them in the style of the image.
never use px in xml. It just need two kinds of pictures,one is xxhdpi,other one is xxxhdpi.If you need a xxxhdpi picture but drop it in xxhdpi's folder.That will influence your memory.So use xxhdpi and xxxhdpi is enough.But you need use dp or match_parent or weight to profile you png's size.
My sample app has these res folders:
drawable-hdpi
drawable-ldpi
drawable-mdpi
drawable-xhdpi
drawable-xxhdpi
In each folder, I have a display.png which shows which folder is from.
I tested my app on my mi max phone which has a density of 440dpi and a resolution of 1920px-by-1080px, but Android always picks the image from the drawable-mdpi folder.
My phone density should be xhdpi, right?
Why is Android picking the image from the mdpi bucket, then?
Create an sample application with below code to check whether it's which density device.
density = getResources().getDisplayMetrics().density;
code will return below values based on your devices 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
I have query, how you came to know the device taking image from mdpi folder ?
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 have a high quality icon. I copied that to drawable-xdpi folder. Can I use icon in drawable-xdpi for low density screens without creating drawable-ldpi folder?
Think it's drawable-xhdpi folder. Yes, Android will look for drawable in the folder that best fits the display type. If it is not found, it will try to determine the next best to use.
yes. Do not put that icon in drawable-ldpi folder.
If your app runs on ldpi device and OS does not found the resources in drawable-ldpi. Then it will use resources from drawable-xhdpi after scaling.
UPDATE
Quality will not be the same..as it is ldpi device.
It will calculate the resolution of new Image like this
resolution of xhdpi icon = x * y
resolution for ldpi will = x/2 * y*2
Why dont u put the image in MDPI or just drawable Folder ?
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.