How should layout and drawable folders be separated properly? - android

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

Related

Layout rescaling with different devices

Sorry about this post which seems easy, but I don’t understand my problem.
I am developing an interface with android studio in xml. I use some PictureButton but I want them to have the same presentation with different devices.
I have put different sizes in folders (hdpi, xhdpi, xxhdpi …) But when I use a device like the nexus 6P I have got this : (Picture 1 - Nexus 6P) and when I use the nexus 10 I’ve got that (Picture 2 - Nexus 10P).
The problem is, these devices are in xxhdpi but they haven’t got the same resolution.
For each button I use this xml code :
<ImageButton android:id="#+id/Collecte"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="50dip"
android:layout_marginLeft="25dip"
android:background="#android:color/transparent"
android:src= "#drawable/nouvellecampagne" />
I don’t understand why they are not rescaling.
Cordially
You should use layout_width="match_parent" and add adjustViewBounds="true" in imageview and let the height to be wrap_content.
The problem is that you giving hardcore dimen value in width and height in this case image take from hdpi xhdpi anything else but you need to define each and every dimen value in dimen value folder value 21, value small ,value large once you setup i think you can see your best result
and visit:-How to define dimens.xml for every different screen size in android?

ImageView to look the same on tablet and phone

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!

Same DPI but different inch size

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!

Android - ImageView - Multiple Screen Support - Set height/width as dp or match_parent/wrap_content?

I am currently trying to adjust my Android App so it will look and feel similar on multiple screens/devices.
I know by now that a major part in this is to provide multiple image sizes for every image file according to the x1, x1.5, x2, x3, x4 ratios for mdpi, hdpi, xhpi, xxhdpi and xxxhdpi respectively, and I have finished doing so today.
After doing this, I have defined Density independent Pixel dimensions in the #dimen.xml values resource that correspond with the actual image sizes in pixels of the MDPI resources. Subsequently, i have set the imageviews in question's layout_width and layout_height to this dimension.
I am currently at a loss, however, as to why my application still looks significantly different on an MDPI emulator than it does on an HDPI emulator. To highlight what I mean, I'll provide the following screenshot showing the HDPI and MPDI emulator next to one another (left is HDPI (4" WVGA Nexus S) and right is MDPI (5.4" FWVGA)). I want both of them to look like the MPDI version, but what I've done so far apparently isn't working.
I have three theories of my own as to why this is not working the way I intend it to:
1. I am not supposed to set ImageView layout_width and layout_height to a dp value, but rather match_parent or wrap_content (?) (and change the structure of my .xml layouts in the process).
2. I am not only supposed to define multiple drawable resources, but also multiple layout resources for different screen sizes (?).
3. I have misunderstood the entire idea behind how this is supposed to work (?).
I will also give you an example of one of the list items that can be seen in the first screenshot (#drawable/phone_speed_icon is a 64 x64 pixel resource in MPDI and a 96x96 resource in HDPI, and #dimen/icon_attribute_size is 64dp):
<LinearLayout
android:id="#+id/llSpeed_PreSession"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingEnd="20dp"
android:paddingStart="20dp"
android:weightSum="100">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="#dimen/icon_attribute_size"
android:layout_weight="20"
android:weightSum="100">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="70"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="#dimen/icon_attribute_size"
android:layout_height="#dimen/icon_attribute_size"
android:src="#drawable/phone_speed_icon" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="30"
android:gravity="center_vertical"
android:paddingStart="10dp"
android:text="Speed"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#878787"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="80"
android:gravity="center">
<android.support.v7.widget.SwitchCompat
android:id="#+id/swSpeed_PreSession"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
In the end, I have four questions that I'd like answered:
1. How do I make the list items in screenshot 1 look the same on MDPI devices as HDPI devices? Does this have anything to do with one of the three theories I mentioned earlier?
2. Why is the header text ("What do you want to measure?") wrapped on one device, but not on the other? They use the sp unit (via android:style/TextApperance.TextApperance.Large)?
3. Shouldn't everything be more spaced out on an HDPI device (if anything) rather than less spaced out? The HDPI emulator looks as if it "has got way less pixels available", if you can understand what I'm saying even a little.
4. How do I make the Fragments on the second screenshot look the same? Or should i not even want this, because the HDPI is (for some reason) physically smaller, which is why the layout is less spread out?
Anyway, I have been at this all day and the more I read the more thouroughly confused I get, so any help is greatly appreciated!
You have the option to create multiple dimens.xml files depending on a variety of factors. Here you'll see what my current project looks like with the various dimens.xml files in Android Studio based on screen width.
However, you can have different requirements for each dimens file you want. For example, you can create dimens files for each density:

Set the imagebutoon for different size of device does not working

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

Categories

Resources