I am relatively new to android. I want to develop an UI which works fine on 2 hpdi devices.
For example lets say on these two devices
Nexus 9
Size 8.86"
Resolution 2560x1600
Density xhdpi
Nexus 10
Size 10.05"
Resolution 2560x1600
Density xhdpi
As seen above both have different screen size and different resolution but density is the same.
My understanding is one layout should work perfectly on both devices, but unfortunately that is not the case. I see differences. Can someone please suggest what changes i should make.
Adding below the portion of the code(xml) which is giving me a problem.
<RelativeLayout
android:id="#+id/rl1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2" >
<customSeekBar
android:id="#+id/abc1"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:layout_marginTop="40dp"
android:thumb="#drawable/eqthumb"
android:progressDrawable="#drawable/progress_eq"
android:max="19"
android:progress="10" />
<TextView
android:id="#+id/abc2 "
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/ abc1"
android:textColor="#FFFFFFFF"
android:layout_marginTop="-10dp"
android:textStyle="bold"
android:text="300"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/abc3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/ abc1"
android:text="0 dB"
android:textColor="#FFFFFFFF"
android:textStyle="bold"
android:singleLine="true"
android:layout_marginTop="-5dp"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
Thank you.
Density is only one part of your layouts though. These devices have different aspect ratios so available device independent pixel (dip or just dp) differs.
So your available width and height differs, but sure logical screen density is the same.
Having said that, android's layouts are rather flexible/adaptable and regardless of screen density. Your layout might need to compensate for different widths or heights though. Just as it might want/need to change due to portrait or landscape mode, different aspect ratios (a potential issue with these two devices) has the same difference.
So you are incorrect in assuming that your layout differs a lot due to hdpi/xhdpi/xxhdpi etc. You might want to qualify your layouts on available screen width or similar (sw720dp for example) instead if needed.
Nexus 9 has a logical screen density of: 1024 x 768 dip
Nexus 10 has a logical screen density of: 1280 x 800 dip
Having said that, your particular layout issue needs your specific xml layouts to be explained. For many layouts those two devices should be able to look the same.
Note: Your device data is off. Nexus 9 is 2048 x 1536 pixels and has an aspect ratio that's 4:3 mind you, compared to 16:10 for the Nexus 10. Both fall in the xhdpi bucket though for resource qualifiers etc. Physical screen density is 288 for the Nexus 9 and 300 for Nexus 10.
As seen above both have different screen size and different resolution but density is the same. My understanding is one layout should work perfectly on both devices
That's not true, you are building on top of this wrong premise. Simply put:
Devices with different screen sizes, but same density, will always work with the same layout
False: different screen sizes (in inches) mean you probably will have to adjust your views. So, provide different layouts, or at least different dimensions.
Devices with different densities, but similar screen sizes, should always work with the same layout
True: if the screen size is the same, a 40dp button will cover the same portion of screen in both devices. That's because dps are density independent pixels, and allow us to work on all densities out there with a single value.
I suggest you read this official resource, that should clear your mind. In the very first bullet list, we read:
Provide different layouts for different screen sizes
Provide different bitmap drawables for different screen densities
As you can see, there's no Provide different layouts for different screen densities, which was the premise of your question. That's just something you don't do usually, it makes no sense if you use (and understand) dps.
Related
I'm developing an app and my Constraint Layout isn't compatible with any screen size.
I have a button with the following width and height:
android:layout_width="283dp"
android:layout_height="57dp"
Here's how it look using a Google Pixel.
And here's how it looks using a Nexus S
I also sent the apk to a person that has an Galaxy J7 (1280x720, 5.5'), and my buttons, textviews and imageviews don't fit well in the screen, just like the Nexus S (800x480, 4').
After reading the documentation and other sources, I got that I can create different layouts for different screens (hdpi, for example, which is the case of the Nexus S).
But it looks that the problem is more related to the display inches than with the device dpi.
Because the Nexus S has an 800x480, hdpi and 4' screen. But when I change to a 800x480, mdpi and 5.1' screen (1.1' more inch), it looks way better than in the Nexus S, even with a lower dpi (mdpi). It also looks better than in the Galaxy J7 real device, even with a lower screen size (5.1' x 5.5') and resolution (800x480 vs 1280x720).
So, how can it fit well in a 800x480 5.1' mdpi screen, but not in a 1280x720 5.5' Galaxy J7 and in a 800x480 4.0' hdpi screen (Nexus S)?
Also, if I create a virtual device with the same screen specs of the Galaxy J7 real device (1280x720 and 5.5'), It fits really well, unlike the real phone.
I advise you to use Adobe XD and use it to determine the size
android:layout_width="283dp"
android:layout_height="57dp"
and after that extract the pictures for all sizes
Then make the width and height wrap_content
In the XML file
You can replace your fixed size (what you are currently giving to your views) with something more responsive.
If this was your non responsive button:
<Button
android:layout_width="200dp"
android:layout_height="400dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Just replace it with this:
<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
For every phone, small or large this button will adjust according to the screen size and will take 30% of the screen width and 50% of the screen Width.
This is how you can make one screen responsive to all screen sizes and not create a lot of layouts for different screens.
These images are OK, it's not a problem itself. That's usually what happens when you set the width and height manually.
Best thing you can do is set the right constraints and then set width and/or height to 0dp. This will make your view expand as much as possible without breaking any constraint. This way you will still get different widths and heights, but hopefully less noticable ones.
Be aware that if you set top and bottom constraints to parent, and you set the height to 0dp, it will expand to fill its contraints, it will fill your whole parent.
And for positioning you can use guidelines if you want. A a horizontal guideline in 50% will be in the middle of the screen in every phone. So you can constrain views to that as well.
I have created a centered layout. But it does not scale images up to device's dpi. How to make them bigger as device screen? Also how to scale them even in editor? Cause I can't. They are always this size.
Here is an example of ImageButton code:
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/broadcasts"
android:background="?android:selectableItemBackground"
android:onClick="onWipButton_Click"
android:layout_marginRight="30dp"
android:layout_marginEnd="30dp"
android:id="#+id/imageButton2"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:scaleType="fitXY"
android:layout_above="#+id/textView5"
android:layout_toLeftOf="#+id/textView5"
android:layout_toStartOf="#+id/textView5" />
Folder structure with all dpi.
On device with high dpi.
Design mode in studio.
I'm assuming you have actually do have assets of different sizes in those resource folders at zoom levels of 1x, 1.5x, 2x, 3x, 4x for m, h, xh, xxh, xxxh.
Then understand that devices are not fixed width either physically or in terms of dps. So while it may be correctly picking the correct resource for the resolution of the screen, that does not mean it will take up the same % of available width on every device. It should just be roughly the same physical size if measure with a ruler (roughly the same mind you).
In the designer, pick a screen with the same width and DPI. You should see the issue at design time.
If you want larger images, providing larger assets would be the simplest solution, and won't make blurry scaled images.
Then if you want the larger images only for larger screens, you could provide the larger assets in a drawable folder for large screens:
res/drawable-mdpi/
res/drawable-sw600dp-mdpi/
res/drawable-hdpi/
res/drawable-sw600dp-hdpi/
etc.
sw600dp is a "smallest width" qualifier, meaning it applies when the device has at least 600dp width available to it. This is a commonly used number to distinguish devices, it's what used to be known as a large screen. If you want to support different assets for 10" tablets, you might also use sw720.
Please see here for more info on the screen size resource folder qualifiers: https://developer.android.com/guide/practices/screens_support.html#NewQualifiers
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/gray"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/darkgray"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/attenders"
android:layout_width="110dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="#color/gray"
android:layout_marginRight="8dp"
android:text="Attenders" />
<Button
android:id="#+id/send"
android:layout_width="110dp"
android:layout_height="40dp"
android:layout_marginLeft="8dp"
android:layout_gravity="center"
android:background="#color/gray"
android:text="Send IM" />
</LinearLayout>
</LinearLayout>
this is my code but the dp is not working fine for all screen resolutions.
suggestions plz, plz tell me if i am doing anything wrong
problem is that when i use dp for setting height or width of a button
it does not gets fits to all resolutions i-e on small screens it looks
big and on big screens it looks small, whereas i know that when we use
dp for setting height and width of any component it automatically
converts/adjusts according to screen resolution
What I understand from this is that you thought using dp instead of px (or in, or cm) will magically work such that they will all have the same physical size on all devices, regardless of that device's density (ppi).
That's not the case.
dp, or dip, as explained here, is
An abstract unit that is based on the physical density of the screen.
These units are relative to a 160 dpi (dots per inch) screen, on which
1dp is roughly equal to 1px.
A screen with more dpi (denser, meaning more pixels are packed into a square area of the screen), will essentially draw a physically smaller image compared to a screen that has 160dpi when tasked to draw the same, say, 100x100 dp image.
When running on a higher density screen, the number of pixels used to
draw 1dp is scaled up by a factor appropriate for the screen's dpi.
Solution
There are two easy ways to have your app look proportionally the same on different screen sizes.
The first is to use different layout folders (layout-ldpi, layout-mdpi, etc.). This technique is well-explained here. A much more recommended way would be to use different style values for each density, so you can still maintain one layout folder and refer to the styles instead for measurement. This can be done using the same technique, but instead you will have values-ldpi, values-mdpi, etc. This is useful for having standard sized UI elements across screen sizes.
The other way is to use weights all over your layout. Weights adjust automatically regardless of screen size of density. This will help a lot if you want, say, three columns that have varying width -- you can easily use weights to tell the layout that column A needs to occupy 40% of the available width of the screen, and B and C will have 30% each. This is useful for having a standard layout across screen sizes.
A clean-looking, nicely coded app will implement both.
It is beacause you are giving fixed dimensions which can only be fit for a particular screen size which you are using. So try avoiding static dimensions and make use of match_parent,wrap_content and fill_parent so that you can get your layout fit for every screen size.
My app works perfectly in resolution 480x800. If I keep the 480x800 resolution but change the screen size to for example 2.7 inches, 3.7 inches or 5.4 inches it still is perfect. But when I change the resolution to for example 640x1066 all the ImageButtons is too small and in the wrong place in all screen sizes... I have created ImageButtons in all four folders(drawable-l, m, h, xh) but still the buttons is not in the correct size..
<ImageButton
android:id="#+id/ib1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginTop="433dp"
android:background="#drawable/imagebutton1" />
<ImageButton
android:id="#+id/ib2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="188dp"
android:layout_marginTop="436dp"
android:background="#drawable/imagebutton2" />
NOTE: My problem is not when I change screen size, but when I change screen resolution.
I would really like to see some code.
If you use RelativeLayout with attributes like android:layout_width and android:layout_height and specify values in dp (density pixels) e.g. android:layout_height="40dp" it should work just fine.
Please try to share some code with us.
Make sure that your assets that you have in your ldpi, mdpi, hdpi and xhdpi folders are scaled correctly to accommodate the diff. resolutions. I accidentally scaled some assets incorrectly, and although they were in the correct folders..gave me some bad results
http://developer.android.com/guide/practices/screens_support.html
My app works perfectly in resolution 480x800. If I keep the 480x800 resolution but change the screen size to for example 2.7 inches, 3.7 inches or 5.4 inches it still is perfect. But when I change the resolution to for example 640x1066 all the ImageButtons is too small and in the wrong place in all screen sizes... I have created ImageButtons in all four folders(drawable-l, m, h, xh) but still the buttons is not in the correct size..
<ImageButton
android:id="#+id/ib1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginTop="433dp"
android:background="#drawable/imagebutton1" />
<ImageButton
android:id="#+id/ib2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="188dp"
android:layout_marginTop="436dp"
android:background="#drawable/imagebutton2" />
NOTE: My problem is not when I change screen size, but when I change screen resolution.
I would really like to see some code.
If you use RelativeLayout with attributes like android:layout_width and android:layout_height and specify values in dp (density pixels) e.g. android:layout_height="40dp" it should work just fine.
Please try to share some code with us.
Make sure that your assets that you have in your ldpi, mdpi, hdpi and xhdpi folders are scaled correctly to accommodate the diff. resolutions. I accidentally scaled some assets incorrectly, and although they were in the correct folders..gave me some bad results
http://developer.android.com/guide/practices/screens_support.html