I have an imageview that is like this
<ImageView
android:layout_width = "wrap_content"
android:layout_height="wrap_content"
android:src = "#drawable/myimage"/>
the image file "myimage.png" is in all the 4 drawable folders for different densities. The view looks good on phone. If I display it on tablet (say 10inch) then the image "looks" too small because there is so much space.
I know I can create layout for it for large screen size, but where do I place the image file with the bigger size? This way the image file can be picked based on not only density but also screen size
Thank you
You should use the sw notation.
For example:
layout/activity_with_photo.xml
layout-sw600dp/activity_with_photo.xml // that's a 7 inch tablet
layout-sw720dp/activity_with_photo.xml // that's a nexus 9 and up
and then the bigger images for those layout
// here a 7 inch tabled with all the densities
layout-mdpi-sw600dp/photo.png
layout-hdpi-sw600dp/photo.png
layout-xdpi-sw600dp/photo.png
layout-xxdpi-sw600dp/photo.png
// here a nexus 9 n up with all densities
layout-mdpi-sw720dp/photo.png
layout-hdpi-sw720dp/photo.png
layout-xdpi-sw270dp/photo.png
layout-xxdpi-sw720dp/photo.png
alternatively, if you're doing appropriate scaling of those resources during runtime, you could add to a no-dpi folder
layout-nodpi-sw600dp/photo.png
layout-nodpi-sw270dp/photo.png
but, if you're using only one, be aware of this here: Bitmap too large to be uploaded into a texture
Simple Steps: -
If you are using stock icons. Go to this site https://material.io/icons/ . Select and download the icon with a size of 48dp.
Extract the zip file and select all the folders under android and copy them into the res folder of your project. That's it.
Screen-size specific resources are denoted by small, medium, large and xlarge. So you need a drawable-small and/or layout-small folder etc.
Source: https://developer.android.com/guide/practices/screens_support.html
EDIT: SCREEN SIZE FOLDERS ARE DEPRECATED since Android 3.2. Please use the density folders
a tricky way is set scaleType of imageView to fitcenter and set constant width and height to your imageview. it will scale up your icon to specified width and height
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="fitCenter"
android:src="#drawable/my_photo"/>
Related
I realise that Android will try it's best if it does not find an icon in the required folder but I see someplaces they suggest all of the above and in others they don't include drawable ?
So should I populate drawable as well if all the others are filled with my tab icon images?
If you use a VectorDrawable, you don't need to add a Resource for every density (mdpi, xhdpi etc). VectorDrawable is supported since API 21 (Lollipop) or with Support Library (or AndroidX).
For simple types of images (usually icons), you can avoid creating separate images for each density by using vector graphics. Because vector graphics define the illustration with geometric line paths instead of pixels, they can be drawn at any size without scaling artifacts.
For images (PNG) on the other hand, you must add proper icons for every density because Android will try to scale the images (so they can proportionally occupy same area in all devices). When scaling, the image may become blurred reducing the quality of your UI.
To provide good graphical qualities on devices with different pixel densities, you should provide multiple versions of each bitmap in your app—one for each density bucket, at a corresponding resolution. Otherwise, Android must scale your bitmap so it occupies the same visible space on each screen, resulting in scaling artifacts such as blurring.
You can read more HERE and HERE
EDIT
Maybe, you don't need to duplicate ALL icons. A lot of factors can lead to different experiences such as using wrap_content or a specific dimension to control the icon size or even using a different scaleType in your ImageView. So, maybe, you can start by adding icons for xhdpi or xxhdpi folders only and check your screen in different screen (small display, large displays, low-resolution displays, high-resolution displays etc). Then, you can "duplicate" only the necessary icons... But if your project or APK size is relatively small, don't mind to duplicate the icons.
There's even some online tools to generate the assets for every density from a single PNG such Android Asset Studio website..
If you are adding all resolution drawable icon like :
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxdpi
then you need not to add any extra icons on drawable folder
because all the device resolution covers under the above drawable folders
There are so many material on densities, multiple screen support, so many questions on SO, but I still have not got it.
My goal is simple: display a bitmap as large as available space for ImageView. I need BitMap as I will do some operations on it.
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/figureView" />
I will have some pictures to be used in the bitmap. I will place them in drawables directory. I will reference them with R.drawable.pictureX. I will use Picasso to load them and scale them:
Bitmap bitmap = Picasso.with(getContext()).load(resourceId).resize(w, h).get();
The unclear part for me is all those xxhdpi folders and Android heuristic to select the best.
When a documentation says that Android will automatically scale the image does it apply to my case? I do not want to scale already scaled pictured.
How many dpi variants shall I store in my case and where? Shall I have single file in no-dpi folder or shall I create picture variant for each dpi folder?
How can I determine a dimension for picture resource? It is easy for icons: for example 24x24 dpi and then multiple it with DPI formula. But I want to cover complete screen height. A chapter Configuration examples lists: 240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 720x1280 mdpi, 800x1280 mdpi etc. There are no screen size qualifiers for resources.
Thanks for clarification.
I realized that in fact it is easy to find out Android behavior. I just need each DPI variant different so I can distinguish between them. I put a text with DPI name and pixel resolution inside each picture.
There is a sample GitHub Test DPI project. It has two ImageViews. The first is initialized from XML and Android does scaling. The second is a placeholder that I fill with a BitMap. I entered 200dp as its size and that was correct. Pixel size of MDPI = size in dp.
What I found is logical. Android does not know anything about my intentions. It just selects the best available resource for current DPI.
Nexus 5x uses XXHDPI by default, Samsung SIII Mini uses HDPI. If I delete their default DPI folders, they down-scale higher available variant: XXXHDPI and XHDPI. If I delete all variants except NODPI, this will be used.
And finally if I change the dimensions of ImageView dynamically loaded from source code to 300dp, then it will be scaled and look ugly. Android cannot know at decodeResource execution that I will scale it later and that there is a better resource available.
What remains unknown is how to find out dimensions of picture that fits the screen.
Java:
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inScaled = false;
Bitmap figureBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_test, opt);
ImageView imageView=(ImageView) findViewById(R.id.testView);
imageView.setImageBitmap(figureBitmap);
Activity:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_test" />
<ImageView
android:id="#+id/testView"
android:layout_width="200dp"
android:layout_height="200dp" />
Update 30th august
Original picture: 230x541 px, loading with
Picasso.with(getContext()).load(R.drawable.amalka).into(target)
stored in nodpi, loaded as 230x541 px Bitmap
stored in xxhdpi, loaded as 230x541 px Bitmap
1.Android will automatically scale image in case when you provided image for one screen dencity and there is no such image for another one. e.g. if you add your image only in drawable-xxxhdpi folder, Android will generate images for xxhdpi, xhdpi screen dencities etc.
2.You can save your image in one folder drawable-xxxhdpi and let Android make the downscale, if you don't like the result you can create images for different dencities on your own.
name dencity scale
mdpi 160dpi x1
hdpi 240dpi x1.5
xhdpi 320dpi x2
xxhdpi 480dpi x3
xxxhdpi 640dpi x4
3.You can define dimensions of your images based on size of you ImageView and dpi scale. For example if your ImageView has width 80dp and height 40dp then your image for drawable-mdpi folder should have size 80x40px because mdpi is a baseline dencity, for drawable-hdpi then you need to have image 120x60px (scale is 1.5) etc. For drawable-xxxhdpi your image will be 320x160px.
If you want your image to fit all the screen on all devices you can use parameter android:scaleType="centerCrop", it will make the image take all the space but little part of image can be hidden depending on screen aspect ratio. You can also try to specify image resorces based on shortest dimension of the available screen area, e.g. drawable-sw720dp. Read more about this here.
I know the Internet is overwhelmed with questions about DPI px inches and so on.
But after several hours of googling my situation doesnt seem to happen to anyone else!
I have 2 devices custom build with android studio which are both mdpi.
BUT one device is 3.65inch and the other device is an 10.1 inch.
I have created a folder with 2 images 250x125 with the dpi set to 160 dpi
If normally I would declare my 2 images in my XML with dp units instead of pixels...I would suppose on both screens the result should be the same right ?
Well it seems the images keep remaining the same size and don't look # how many inch the device is
So to set things clear:
What do I have to change at my resources or my code so that my layout scales identical for different Inch sizes ?
This is my GOOD layout for my mdpi 10.1 tablet :
This is my BAD layout for my mdpi 3.65 device
How can I make it so that even on the 3.65 inch screen the buttons will scale to the same PROPORTIONS as the 10.1. Not the inches...not the pixels...the proportions....
This is my XML File
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="#+id/buttonEnglish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/english"
android:layout_marginBottom="5sp"
android:layout_marginLeft="5sp"
android:layout_marginRight="2sp"
android:layout_marginTop="0sp" />
<Button
android:id="#+id/buttonNederlands"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/nederlands"
android:layout_marginBottom="5sp"
android:layout_marginLeft="20sp"
android:layout_marginRight="5sp"
android:layout_marginTop="0sp"
/>
</LinearLayout>
I'm desperate...
Thanx in advance
This might help explain the problem you are facing...
You have an image that is 250x125 - that is 250 pixels wide by 125 pixels in height.
You have specified 160 dpi - which means that 1 inch = 160 pixels.
So, both screens are doing what you ask and displaying the 250 pixels across 1.5625 inches. On the large screen it looks "proportionally" correct. On the 3.65" screen the button takes up more than half the screen - just like you asked it to.
If you want the smaller screen to look like the larger screen, then you have three options:
adjust the size of the image and provide 2 image assets (or more for a wider variety of screens). This is why you can have resource folders for mdpi, hdpi, xhdpi, etc. You adjust the pixels in the image to accommodate the screen size.
You use a "weighted" LinearLayout that adjusts the size of the space provided based on the available screen space. For this type of layout you should not worry about performance.
Do runtime scaling of the image based on screen size - use DisplayMetrics to get the size and density of the screen and adjust your image to fit the screen appropriately.
The last option is the most flexible in many ways, because if you end up with a screen that is either very large or very small, you can make adjustments to do things like move buttons or text to another place on the screen (above or below other content). But for your specific problem, any of them will suffice.
There is no need of Designing two xml layout.
You can use Dimension for margin and padding according to device.
You are giving static value for margin.
Use dimen.xml in value folder each device.
Following code in your layout.xml will work for you.
android:layout_marginLeft="#dimen/margin_button"
Value folder name for dimen.xml:
values-mdpi
values-hdpi
values-xhdpi
values-xxhdpi
values-sw600dp
create dimen.xml in each values folder.
and in dimen.xml you have to define value for margin in all values folder but value of that property is different according to device size like this:
values-mdpi
<dimen name="margin_button">20dp</dimen>
values-hdpi
<dimen name="margin_button">23dp</dimen>
like wise in all values folders.
Thanx everyone for the answers. Due to answer from #Iacs I discovered that I had to made changes to my folder structure.
I have completely overlooked the fact that in the /res folder there can be more directories then just the standard "layout" directory. You can create other directories with these names : layout-large, layout-xlarge, layout-small, and so on...
In these folders you can paste your layout.xml and adjust the values...
This is how things look now in my android studio
note the layout folder structure:
And now ofcourse my 2 devices with both the same DPI but different screen size are showing my buttons the way I want them to be showned!
I am going to develop new application in Android. This application should only work in portrait (even for tablet). Also the UI and layout design should be similar on phones and tablet. We can't change the layout design for tablet as it has huge area to use. We have to stretch all the images to match phones. We can use nine patch. But I am little bit confused of using images in multiple drawables.
As per my analysis (may be wrong.. : ) ) the screens are divided into density and sizes. We can use the scaling ratio of 3:4:6:8. But this ratio is based on the density. But in my case I have to stretch the entire UI to fill the Tablet screen.
So what are the drawables that can be used for a app like this which can support multiple devices. And what are the screen sizes for which we have to design.
And this application needs nearly 100 layouts. So I am planning to maintain single layout and designing the layout using weight for each layout instead of using dimension.
Also if I used multiple APKs to support different screen size what are the drawables used to support
1. Small and Normal
2. Large
3. Xlarge
I just did something very similar. To stretch the app without creating new layouts I used dimensions set in XML
res/values/dimensions.xml
res/values-sw600dp/dimensions.xml -> 7+ inches
res/values-sw720dp/dimensions.xml -> 10+ inches
Dimensions are resources files:
<dimen name="default_padding">11dp</dimen>
You can increase the dimensions by about 30% in the 600 and 720 file.
Then simply used #dimen/default_padding in your layout and it will be scaled
Regarding images, either you make sure you have all your assets in all densities, or you set fixed size to you ImageView's and appropriate scaleType
Firstly, you do NOT want to create multiple APKs to support multiple screen densities. Android provides all of the framework you need to support everything within one build, you just need to create the right resource hierarchy drawables with your desired densities.
So what exactly do you need... based on your question the following:
portrait mode: you can specify this in each Activity declared in your AndroidManifest file using the following:
<activity android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="orientation" >
...
</activity>
NOTE: Per the Android docs, if you're targeting API >= 13, and you use the android:configChanges attribute you should also use the android:screenSize attribute to help specify size changes.
dimension sizes for various screens: as touched upon, this can also be handled in resources. This is your best way to use one common layout file but configure the layout for use on numerous devices. See http://developer.android.com/guide/topics/resources/more-resources.html#Dimension for how to use dimensions if you're unfamiliar
drawables: it sounds like this is the crux of your question. As you mentioned, using nine-patches will help you reduce your app footprint and fill in extra space (see here and here for more on nine-patches). The sizes you should support and the densities needed for those sizes are discussed in great detail in Android design docs, so much detail I could not even do it justice rehashing it here. I've provided links below to as many places as I could remember that this is discussed.
Good luck!
Here are links to Android design docs that you will find useful (some of which have been mentioned):
http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
http://developer.android.com/training/multiscreen/index.html
http://developer.android.com/guide/practices/screens_support.html
http://developer.android.com/design/style/devices-displays.html
In addition to the pixel density specific folders, you can specify screen-size specific folders
drawable/
drawable-large/
drawable-xlarge/
drawable-hdpi/
drawable-large-hdpi/
drawable-xlarge-hdpi/
drawable-xhdpi/
drawable-large-xhdpi/
drawable-xlarge-xhdpi/
So you could design scale appropriate graphics for the various screen sizes and densities. Please note that a give screen size category (e.g. "large") will only give you a rough idea as to the actual device pixel dimensions of the device, but you'll get good guidelines for min/max dp ranges.
For example, you might have a 100x100 image you want to display on phones (screen size "normal"), you'd create image assets at 100x100, 150x150, 200x200 for drawable, drawable-hdpi, drawable-xhdpi folders respectively. But on 7" tablets, i.e. "large" screen size devices, you might display this same image at 200x200, so your "drawable-large" folder assets would be 200x200, 300x300, 400x400, and on 10" tablets, i.e. "xlarge" screens, you might display the same image at 300x300, 450x450, 600x600, so these go in "drawable-xlarge-*" folders.
All the details are here:
http://developer.android.com/guide/practices/screens_support.html
First you need all the possible screen layouts
drawable
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi // phones like s4
drawable-xlarge
drawable-tvdpi // nexus 7 etc
drawable-xlarge-xhdpi //tablet like nexus 10
layout : for phone
layout-sw600dp
layout-sw720dp
then you need to put all use 9- patch images for buttons etc ... you can also make your custom drawable it would be easy and handy to work on ..Also you can take dpi for each screen by using switch and scale it the layout accordingly.
As, in one of my project I had used this technique for showing respective thing to each resolution device .
DisplayMetrics metrics = getResources().getDisplayMetrics();
int densityDpi = (int) metrics.density ;
switch (densityDpi) {
case (int) 1.5:
break;
case (int) 2: //1.75 will be 2 in INT.
break;
default:
break;
}
also keep all the values you are going to used for margin padding etc values-sw600dp for tvdpi tablet ,value-sw720dp for tablets
Last but not least keep all thing generic as much as you can and put it in drawable ..
I have seen some ppl who used background patterns of different dpi's and put it in respective drawable .. if there is such thing like pattern make your custom drawble and repeat it accordingly
that will save your time .. hope it may help you
In order to stretch all the images to match phones you can specify the image size using the sdp size unit. This size unit is relative to the screen size so it can fulfill your requirement.
i am putting the image in three of the drawable,drawable-hdpi and drawable-ldpi for supporting all type of screen but when i see the output of background image in 240*320 screen resolution the background image is not as clear as origional so my question is where to, means in which folder i put the background image for supporting it all type of screen size and density, maens then my image should not distorted or bluer...
i am using the background image of size:320*480
thanks
make one folder name
drawable-nodpi
put your image in that and use it and dont keep that image in other folders.
the image will not be scaled or stretched.
Anoher Way
the best way is to make 3 different size images and put int drawable-ldpi(240X320),drawable-mdpi(320X480),drawable-hdpi(480X800) folder with the same name.
TO LEARN MORE PLEASE VISIT THIS LINK.
Supporting Multiple SCreens
You can put different same image in drawable-hdpi,mdpi and ldpi.Depending on the density of devices they will take the images from the corresponding folder.
With different devices you should have same image but with different size and density.for You can search in internet the specifications of devices.If density is less than 160 then put image in ldpi,if 160 then use mdpi and if 240 or above use hdpi.Also change the size of image to the screen size of corresponding device.Hope it will help.