So If its in DP, It should scale itself according to the different screen sizes, but that's not the case when i define fixed width and height to an image,it opens it slightly smaller on high res phones, and slightly bigger on low res phones.
I don't know that either this is an expected behavior or i am missing something here.
I am testing on Samsung s5 and Samsung S7 Edge
Samsung s5 is 432 ppi pixel density
Samsung s7 edge is 534 ppi
I have added a single image in my layout for testing. I have added 4 different sizes drawables for it.
<ImageView
android:layout_width="180dp"
android:layout_height="200dp"
android:src="#drawable/testimage"
/>
Now when i open the same project on s5 and s7 edge, the output is little different. It would be understandable if it was appearing larger on high res phone, but on s7 edge, the image is looking smaller than s5.
Kindly guide me that is it a normal behavior or i am missing something here.
Measuring something in dp means it will be the same physical size, not the same percentage of the screen size, so this is entirely expected.
You can certainly use the Percent Support Library (see the details on this Google+ post to make views a set percentage of the layout's width or height, but you should probably only do that if you use vector drawables that will scale appropriately (otherwise, it will be blurry at some level). Generally you'd want to use the additional space on devices to show more content.
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:src="#drawable/testimage" />
</android.support.percent.PercentRelativeLayout>
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.
Sounds like a basic question but I have no idea why this behaviour is that way
I am using a button that is 200 dp by 60dp and with 15sp text size
It looks good on my phone, emulator and multiple other 5 even low 6 inches phones
However on note 10+ which is 6.8 inches, the button looks smaller and the text is smaller
I thought when using dp and sp, it will occupy the same size on all phones given that it is in terms of density independent pixels
Why is this behaviour?
Thank you
Update:
Based on this page about dp size of devices and the link provided at the top of it, I've reached to this article how to calculate metrics of any device including dp. Based on my calculations Note 10+(3040*1440 pixel, 495 ppi) is a 465 * 982 dp device. Google pixel you can see from the first link is a 411 * 731 dp device. So, if you create a size 200 dp layout it would be smaller on the note 10 + than on the google pixel for example. To be honest I thought all small screen devices are something close to a 360 width dp and expected that one design by dp would be seen roughly the same on all devices. I was wrong apparently. It seems if the layout is supposed to be seen exactly the same width on all devices there is no way but to set its width by a percentage of screen width. Google doc has it too: converting pixel to dp.
This image from Support different pixel densities lead me to incorrectly think that designing by dp would be seen the same on all devices. But it would be seen the same only on same dp devices.
It looks good on my phone, emulator and multiple other 5 even low 6 inches phones,
As #Mr. Patel mentioned in his comment, you can use ssp and sdp but I want to offer another solution.
First - why is this happening:
You have a lot of different phones with a lot of different screen sizes, when you are using dp you are actually using a fixed size value - it can not be scaled for large screen.
How to fix it:
You can use ConstraintLayout
with percentage to make your views scale according to the screen size.
Example:
Let`s have a look at this layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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" />
</androidx.constraintlayout.widget.ConstraintLayout>
It will look like this:
In this layout, the button size is 200dp and 400dp.
This may look good on one phone but will not look good on another phone, because as I have mentioned before:
different phones = different screen sizes.
Let`s take a look at how to make your layout responsive according to the screen size:
All I need to do Is to change my layout to this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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" />
</androidx.constraintlayout.widget.ConstraintLayout>
And now the layout will look like this:
Looks... kind of the same?
Well, the new layout is actually looking not so different from the original but now because I have added those attributes:
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintHeight_percent="0.5"
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.
Another tools that can help in the prosses of making some screen responsive:
chains
barriers
How to add different weight to ConstraintLayout views
Autosizing TextViews
dp is base on screen resolution (px) and dpi.
Example:
1280x720px screen of xhdpi (x2)(320dpi) will have 640x360 dp => 1dp = 2 px in that screen.
640x360px screen of mdpi (1x)(160dpi) will have 640x360 dp => 1dp = 1 px in that screen.
The result will look the same for 2 devices
But when the device have a smaller dpi (240) but remain the same resolution: 1280x720px it will have ~854x480 dp
=> 1 = 1.5px in that screen => Your button and text will look smaller.
To make your button look the same on multi screen, you have to provide many dimens file for many screen.
You will have to use many dimens file to make your button show the correct size on other screen. (ssp and sdp is use this way) - (My project have tons of dimens file for each 10dp different screen size to make sure app show the same on any device)
Or you have to use percent supported layout (ConstraintLayout, PercentRelativeLayout, ...)
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.
I am designing an app which needs the customized button. I made it by inheriting the Android Button and I set its width to 300dp in the layout xml. However, I found the size of button is changing on different devices. Here are the example:
My UI in the original device: Galaxy S5
My UI in the new device: Nexus 5X
My UI in another device: Galaxy Note4
(In this trial, I set the left button to use sp instead of dp)
It seems the whole layout scale is smaller in my new device even though both of them are 1080 x 1920 pixels.
I also try to use sp but it behaves the same (problem). My guess is the style? Can any one gives me more thoughts. Thanks!
--- UPDATE ---
Hi, let me rephrase my problem.
I am looking for a way to make a button which width is fix to like (relatively) 1/3 screen width at any device. And its text also changes accordingly. I think the ultimate way is to translate everything to pixel and assign those value manually in program. I used to think using dp and sp is an easy alternative to achieve it, but it turns out not :(
To set width of each child programmaticaly,
view.getLayoutParams().width = getScreenWidth() / VIEWS_COUNT_TO_DISPLAY;
And Screensize as below
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics).widthPixels;
Now, If you want to set Text than use SP for that.
If you are using dp then it will change according to device's screen density. In order to keep the button size same in different screen density conditions you need to use pt,in or mm in your button's width.
Please check link : What is the difference between "px", "dp", "dip" and "sp" on Android?
I think here is what you want.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:weightSum="3">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/test"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Normal Charge (Testing)"/>
</LinearLayout>
</LinearLayout>
With the use of weightSum and layout_weight, you can fix the item as 1/3 width of your screen.
Inside the imageview, android:scaleType="fitXY"
It means that the image will be changed to size in order to match the size of imageview.
You can delete that attribute if you do not want that.
For the image, the best way is to prepare different size of the image inside different folders:
for mdpi it should be 100X100
for ldpi it should be 75X75
for hdpi it should be 150X150 (e.g. Xperia U)
for xhdpi it should be 200X200 (e.g. Galaxy S3, Galaxy Note II, Xperia S)
for xxhdpi it should be 300X300 (e.g. Galaxy S4, Galaxy S5, Xperia Z, Xperia Z1, Xperia Z2)
The above size is just an example, you have to find the base case, i can explain more about that if you need.
Hop that can help, thanks!
Ok here is a problem that is puzzelling me that I really would like you to help me out with.
I am testing my app with both HTC amaze and Galaxy S2 (as I know both are High density) and both in the 3.7-4.3 screen range
The problem is that the same image looks different in terms of size on both screens. On The HTC amaze it is much smaller. I have my 3 drawable folders with the appropriate different sizes ( which I should need anyways here because both devices are of the same density)
I did some debugging on the DisplayMatrics and I found for HTC amaze the follows:
density 1.5
desnityDPI 240
Height pixels:540
Width pixels:960
xdpi 258
ydpi 256
However, for the S2 galaxy the display metrics are:
density 1.5
desnityDPI 240
Height pixels:480
Width pixels:800
xdpi 160
ydpi 160
So can someone explain to me why the images sizes on both devices are different. On HTC amaze images are much smaller than on the S2?
Thank you
Edit: Code used to get the DP info is
DisplayMetrics mt =getApplicationContext().getResources().getDisplayMetrics();
EDIT:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/carpet"
android:clipChildren="false"
android:clipToPadding="false"
android:keepScreenOn="true" >
<RelativeLayout
android:id="#+id/relativeLayoutBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:clipChildren="false"
android:clipToPadding="false" >
<ImageView
android:id="#+id/ivBottom1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/ivBottom2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp" />
<ImageView
android:id="#+id/ivBottom3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp" />
</RelativeLayout>
</RelativeLayout>
private void initialize(ArrayList<CardSuitNumber> cards) {
RelativeLayout flBottom = (RelativeLayout) findViewById(R.id.relativeLayoutBottom);
player1.clearAll();
for(int i=0; i<GameConstants.MAXRANKS;i++){
player1.addCard((ImageView)flBottom.getChildAt(i));
}
}
public void addCard(ImageView im){
Drawable drawable = card.getCardSuitNumber().getDrawable(mActivity);
im.setImageDrawable(drawable);
imsetVisibility(View.VISIBLE);
}
The answer is in the numbers right in front of you.
Source http://www.androidauthority.com/htc-amaze-4g-vs-samsung-galaxy-s-ii-t-mobile-27110/
In terms of screen size, the Samsung Galaxy S2 has a slightly larger
screen with 4.52 inches of display. The HTC Amaze 4G, on the other
hand, comes with a screen similar in size to the international variant
of the Galaxy S2–4.3 inches.
The HTC Amaze has a higher resolution, and a smaller physical screen. This results in a higher pixel density- that means smaller physical pixels, because a larger number of them needs to be crammed into a tighter place.
An image of for example 240x160 would therefore appear smaller on the Amaze.
The reported DPI values for the S2 is clearly wrong. According to the metrics given it is '
800/ 160 = 5 inches on the long side, and 480/160 = 3 inches on the short side.
This would have given a screen size of sqrt (5 * 5 + 3*3 ) = 5,8 inches.
The DPI values for The amaze is correct. As we see if we do a simple pythagoras. Sqrt (960/258^2 + 540/256^2) = 4,27"
As a developer I experience the same thing when moving from my test device HTC sensation, and the S2.
The xdpi and ydpi on HTC is very high thats why the image is smaller.
I remember there was a bug that the reported xdpi and ydpi was totaly wrong, and to be honest they look wrong.
Would this be related to this issue: https://groups.google.com/forum/?fromgroups#!topic/android-developers/g56jV0Hora0
I am not sure but the One Solution that i come to know base on your issue is, You have to made the layout as per the Device Screen Resolution.
As like,
Galaxy SII Support layout-normal-hdpi
As like,
Maybe HTC amaze support layout-large Screen.
So try to make the Layout as per the Device and it will solved your issue.
Hope it will help You.
Other detail that same to your question is here: android-layout-issue-for-htc-evo-3d
Enjoy Coding. . . . :)