I have an imageview that is within a cardview to create a circle image. On a smart phone, I want the size of the image to be 250 and 250dp, let's say that is about 80% of my phone width.
On a tablet, I want the image to be about 80% of the width of my tablet, and the height must also match the width. What's the best way to achieve it. Thanks?
Following is the code where I manually put the width and height of 250dp, which looks fine on smartphone, but way to small for tablet.
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_width="250dp"
android:layout_height="250dp"
android:elevation="12dp"
app:cardCornerRadius="125dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9"
android:layout_marginTop="20dp">
<ImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:id="#+id/image_album_art"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
</ImageView>
</android.support.v7.widget.CardView>
Android is designed to make this easy. If you want a resource to change depending on the device configuration (i.e. screen size), you define that resource in a specific directory:
res/layout-sw720dp - large (9"-10") tablets
res/layout-sw600dp - small (7"-8") tablets
res/layout - all other devices
When you append -sw600dp to the directory name, this means "smallest width 600 dp". This means that this directory is meant for devices that have a screen width of 600dp or greater. "Smallest width" means whichever side of the screen is smaller, so whether it's in portrait or landscape, a 1067dp x 600dp screen counts as having a smallest width of 600dp.
You can make a copy of your entire layout file for each configuration and put one in each of the above directories. However, if all of the files are the same except for the View sizes, you will have a lot of duplicate code. If you need to make a change, you will have to make that change in all three files, which can lead to mistakes.
Instead of having multiple layouts, you can define a dimension that varies according to configuration. Layouts go in res/layout/, and dimensions go in res/values/
Create a new XML file dimensions.xml and put it in the res/values directory. Add a new dimen to it like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="album_art_size">250dp</dimen>
</resources>
This will be the file that phones will see.
Then, create two more values directories and append the smallest-width qualifier to them, so you have res/values, res/values-sw600dp and res/values-sw720dp. Copy dimensions.xml into both of those new direcories. You can then modify the album_art_size dimen in each of those files, and when your app runs on different screen sizes, it will see the appropriate dimensions.xml file.
The last thing to do is to point your layout at the album_art_size dimension you have just created. Replace 250dp with #dimen/album_art_size:
android:layout_width="#dimen/album_art_size"
android:layout_height="#dimen/album_art_size"
This will allow you to pick specific dimensions for each device category, which should get you close enough to your 80% screen size target. If you need exactly 80% of the screen width and a square View, you will need to fiddle with ImageView's scaleType and adjustViewBounds attributes or write some Java code.
What you can do is create a folder of layout of type large ie layout-large and then copy the layout from layout folder and paste it in layout-large folder and then just set height and width according to the screen size of tablet ie may be 450dp or so do check that!
Related
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"/>
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 add the picture for 48*48 , 72*72 and 96*96 to mdpi , ldpi and hdpi respective.
And add the following code in AndroidManifest.xml
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>
First Question:
The app will capture the suitable picture by itself when I do the above operation ?
Second Question:
But how to setup the Button in the xml file ?
If app will capture the suitable picture by itself , so I have set the width and the height to match_parent like the following code?
<LinearLayout
android:id="#+id/ImageBtulayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical"
android:background="#000000"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageButton
android:id="#+id/BackButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_gravity="center_vertical"
android:background="#drawable/back"/>
<ImageButton
android:id="#+id/recordButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center_vertical"
android:background="#drawable/no_delete" />
<ImageButton
android:id="#+id/download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:background="#drawable/download"/>
</RelativeLayout>
</LinearLayout>
I modify the code like the above.
And I install the APP to the device which the size is 4.7 inch.
But the icon seem too small.
It like the following picture
How to remove the part of gray on imageButton ?
Does there has any wrong ??
You are confusing two different concepts. One is a screen's pixel density or DPI and another is a screen's size. In general, phones are considered normal size and tablets are considered large size.
I recommend you read through this entire article which highlights a lot of valuable points regarding supporting different screen sizes and screen densities:
http://developer.android.com/guide/practices/screens_support.html
In general though, Android allows the user to define different resources for different device configurations (including screen size and screen density, among others). This is done through the use of (resource/configuration) qualifiers. These are defined by a hiphen, and then the qualifier name on certain folders inside your /res/ directory.
For example, if you wanted to define different images for different screen densities, you would create a new drawable directory for each supported screen density and put the appropriate resources in each.
/res/drawable-mdpi/
/res/drawable-ldpi/
/res/drawable-hdpi/
Then, when Android goes to look for a resource, it will first look for a directory which matches the device's screen density qualifier and get's the resource from there. The resources will share the same name, but will be in different folders, which allows you to define the different resources but also allows Android to resolve them into their different configurations.
So let's look at your questions:
The app will capture the suitable picture by itself when I do the above operation?
As described above, as long as you have arranged yor resources with the appropriate qualifiers, then yes, Android will be able to resolve them correctly. However, note that this has nothing to do with the tag in your manifest.
But how to setup the Button in the xml file ?
Your current XML setup is correct.
If app will capture the suitable picture by itself , so I have set the width and the height to match_parent like the following code?
Setting your width and height to match_parent will make the views width and height the same as the parent layout, which is incorrect. You want the width and height to wrap the internal content of the view, therefore wrap_content is correct.
Edit: Regarding your question about removing the border, if you want to use ImageButtons, then the documentation (first paragraph) suggests setting the android:background attribute to transparent.
android:background="#00000000"
You might also want to try setting the padding to
android:padding="0dp"
http://developer.android.com/reference/android/widget/ImageButton.html
Answer for the first question:
Android system will choose the image in drawable folder according to device screen density.
Answer for the second question:
If the previous code, you set the height and width of the ImageButton to be wrap_content, so the width and height of the ImageButton will be as the size of the captured image from drawable folder, so if you run on device hdpi then the image size (72*72) and the ImageButton dimensions will be also (72*72) px.
In image button Set Android:src="#drawable/your image"
and set android:background="#null"
it will definatily work for you
I'm trying to make application run on each device and I come to a problem of making layouts and drawable folders. So, as I'm understanding ratio dpi is following - mdi:hdpi:xhdpi:xxhdpi - 1:1.5:2:3. DPI stands for dots per inch and this dots are actually presenting "DP" as density pixels which we put into XML attribute like: android:layout_width="150dp". (Please, correct me if I'm mistaking)
Problem occurs that some devices can have let's say 240x320 with xhdpi and there can be device 720x1280 also with xhdpi. Even if i would make separated pictures with already mentioned ratio, I would still need to make separated layouts in which:
layout-small would have something like this for ImageView:
<ImageView
android:id="#+id/slikaPitanja"
android:layout_width="150dp"
android:layout_height="100dp"
android:visibility="gone"
android:layout_below="#+id/sadrzajTekstualnogPitanja"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:contentDescription="Country flag" />
and layout-large where I would have the same code for ImageView except I would have these lines:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
(Actually I could have layouts separated with sw_ _ _dp format).
Is that right to do it like this? Am I missing point somewhere? Something tells me that it's never good to manually determine dps in width and height as I would for layout-small.
Try to NOT use static dpi for your layout, Instead use "wrap_content , fill-parent and gravity". this will make your layout to spread dynamically depending on the screen size
I have an app that displays a bitmap in a TextView as a "drawableTop":
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawableTop="#drawable/bitmap"
android:gravity="center"
android:text="#string/text" />
The bitmap comes from a PNG file in the res/drawable folder, let's call it bitmap.png.
I need to support multiple screen sizes and densities, and want to find the cheapest way (in term of how many PNG files I need to have in res/* folders) to do it.
Various densities: Phones only
I've come to the conclusion that it's enough to have the bitmap.png in res/drawable-xhdpi folder. When being displayed on phones with high density, it will be displayed as is, while on phones will lower density, it will be scaled down automatically.
In other words, no need for having lower resolution versions of the bitmap.png in res/drawable-hdpi, res/drawable-mdpi etc.
Basically only one version of the PNG file is enough for all phones.
Various densities: Tablets as well
Now, the problem arises if I want to support as well tablets: large and xlarge screens.
On tablets, I want the aspect ratio of the icon to be the same as it was on phones: If the bitmap took 1/4 of the screen on phones, I want it to take 1/4 of the screen on tablets. I cannot reuse the same PNG file as before or it would look too small since the tablet just has more pixels... So for tablets I need a higher res PNG. And this applies both to large screen and xlarge screens.
Which results in the need for 3 folders, and 3 versions of the PNG:
1: res/drawable-xhdpi/bitmap.png
2: res/drawable-large-xhdpi/bitmap.png
3: res/drawable-xlarge-xhdpi/bitmap.png
But 1 and 2 are basically lower res versions of 3.
So is there an easy way to have a single folder not 3?
If you want to keep only one image for all resolutions, why not keep in res/drawable and res/drawable-land folders?
If you are talking about cheapest way to do this (not adding more than one image in drawables), then use 9-Patch Images. If you dont know about it, then have a look n learn usage here:
http://www.androiddom.com/2011/05/android-9-patch-image-tutorial.html
http://www.androiddom.com/2011/05/creating-custom-drawn-button.html
Judging from your question, you don't need different orientated images for tablet or phone.
If you want the image to take 1/4 size on both devices, then define your image in your xml as using d(i)p. This will scale the image to the same size on all devices.
d(i)p is scaled relative to 640x480 (or 480x640 resolution for portrait orientation).
So you can calculate different combinations of resolutions to cover 1/4 screen space, such as 320x240 or 240x320
If you want control over the scaling of your image, I would suggest putting the image in an ImageView. This will allow you to use the android:scaleType property to scale your image how you wish.
You can set the background of your TextView to be transparent, and have the ImageView below it contained within a relativeLayout of your desired size to achieve the same effect as you current have, like so:
<RelativeLayout
android:layout_width="320dp"
android:layout_height="240dp"
>
<!-- Images at the top of the xml are drawn on the bottom! -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="#drawable/bitmap"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/text"
/>
</RelativeLayout>
Also consider using alias resources.
This will allow you to define an xml file which will act as if it's the real PNG image (and is referenced as such in R.drawable. , but is actually a reference to another image.
From the linked Google documentation:
To create an alias to an existing drawable, use the element.
For example:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/icon_ca" />
If you save this file as icon.xml (in an alternative resource
directory, such as res/drawable-en-rCA/), it is compiled into a
resource that you can reference as R.drawable.icon, but is actually an
alias for the R.drawable.icon_ca resource (which is saved in
res/drawable/).