I created my app to support screens from hdpi to xxxdpi and everything was working perfect. Images were shown just like they're supposed to. But, now I have a problem with Xiaomi Mi Max 3. It has 6,9" display with a resolution of only 1080x2160 which gives a ~350 dpi. That falls into xhdpi category (usually 720p screens) and now my images are smaller then they should be. Is there any way to force the use of drawable-xxhdpi folder with code?
just create another file like as:
drawable-xxxdpi/example.png
drawable-anydpi-v21/example.xml
and link your image file from anydpi xml code for supporting every screen size.
see more information from official website or visit What Is The Difference Between -anydpi And -nodpi?
Ok, thanks to Md.Abdullah I found a solution.
You cannot choose which folder of resources to use but you can use specific resource from a folder with getDrawableForDensity() method. This is what I did:
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
int dpi = getResources().getDisplayMetrics().densityDpi;
int imageID = R.drawable.YOURIMAGE;
if (width > VALUE && dpi < VALUE) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
Drawable drawable = getResources().getDrawableForDensity(imageId, DisplayMetrics.DENSITY_XXHIGH);
//you will probably need to adjust width & height of your ImageView, but since the image
//will keep its aspect ratio, you only have to change width | heigth
YOURIMAGEVIEW.setAdjustViewBounds(true);
YOURIMAGEVIEW.setMaxWidth(VALUE);
YOURIMAGEVIEW.setImageDrawable(drawable);
}
}
Related
I want to programmatically set in my layout size. And this layout size get from dimen folder. but the problem is when I get the value from dimen folder, It gets displayed in a normal resolution screen perfectly but when it runs in a high display resolution it doesn't run perfectly
You can set layout size programmatically by using one of the following ways:
Method 1:
int width = getResources().getDimensionPixelSize(R.dimen.layout_width);
int height = getResources().getDimensionPixelSize(R.dimen.layout_height);
Method 2:
int width = (int) (widthdpValue * Resources.getSystem().getDisplayMetrics().density);
int height = (int) (heightdpValue * Resources.getSystem().getDisplayMetrics().density);`
Set this width and height to the layout.
You have to convert the dp value you get from the dimen folder into the proper number of pixels for the device's screen density. Example:
float dp = 5.0f // This is the dp value from your dimen file
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
Where px is the scaled pixel value that will properly display on the device.
Refer to this link Different values folders in android!
Create a "values" folder for each screen density and define the size of your layout in each "dimensions.xml" file. This will give you the ability to use different sizes for the same layout without using any piece of Java code.
Hope this helps :)
Yes I solved my screen resolution problem.
When you get value from dimen folder it get in Pixel format. And Pixel size depends on your device resolution Not device size.
So you need create screen size and screen resolution based dimen folder. As like:
In this folder categorized in different screen size and different screen resolution.
You can't use only one dimens for all the devices layout, please try to create some value resouce folder with different size
And u can refer to my project as below which can help u to gen the dimens in different floder automatically
https://github.com/Vaycent/genDimensXml
I hope this can help u
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 have a bitmap with the dimensions of 537 * 233. This is displayed in my fragment.
I am calculating the height of this bitmap through code as well.
I came to know that simply using,
image.getHeight() will always return 0.
Then I found that putting the same in overridden method onGlobalLayout() will give the actual height.
I did that. See my SO post for link.
Now the height I am getting is 155.
I also tried getting the height with,
BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.chart);
imgHeight = bd.getBitmap().getHeight();
Again the height I am getting is 155.
According to the above dimensions, the height should be 233.
I am seeing the same height in emulator too.
Why is the difference and/or what I consider to be its actual height ?
UPDATE:
ok, my chart was in drawable-hdpi and the density of my device is 160. So when I put the chart image in drawable folder, I got the correct height. But then if the chart height is fixed (233), why in some devices I am getting the chart height big enough to overlap my bottom timeline. Although I know a bit that this may be because of approximate values and not accurate values (density, resolution) that is causing the in-differences. But then, Any ideas how to fix that ?
First you know mdpi = 1, hdpi = 1.5 and xhdpi = 2.
Lets say you have an image in mdpi folder with width = 100px.
On mdpi device the image width will be 100x1 = 100px,
On hdpi device 100x1.5 = 150px,
On xhdpi device 100x2 = 200px.
if you dont have the image in hdpi or xhdpi folders the android system will scale them.
So when you have an Image in hdpi folder and you run the app on medium density device (mdpi), the android will scale down the image by 1.5. 233 / 1.5 = 155.
The same will happend if run the app to hdpi device you will get an image with ~310 width.
So, to avoid the scaling i suggest to put the image in drawable-nodpi folder (the images in this folder will not scaled by android system).
PS: if you put the image in drawable folder and run in mdpi device the image will not scaled because drawable folder = drawable-mdpi
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 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.