2

I have an activity with three rectangle CardViews. I have set the size constraints such that they change according to the screen resolution. Please view my constraints here.

The problem is that the CardViews are not changing their size proportionally. For example, when I run my application on a Nexus 5 (1080 x 1920), the bottom component gets cut in half, where as if I run on a Pixel (also 1080 x 1920), the bottom component is the desired size.

Although I will try to make the post as clear as possible, the pictures definitely help understand the problem I am facing, so please view them.

..

Why is the bottom component changing so drastically when the screen sizes are very similar? How can I modify the components so that they are the desired size for these different screen sizes?

I know that you are able to create small, normal, large, and xlarge layouts, and I have but I don't think this is what the problem is.

Code for the 3 CardViews:

Top left

    <android.support.v7.widget.CardView
        android:id="@+id/capture_receipt_cardview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="@dimen/margin_width_normal"
        android:layout_marginEnd="@dimen/button_gap_normal"
        android:clickable="true"
        android:foreground="?android:attr/selectableItemBackground"
        app:layout_constraintBottom_toBottomOf="@+id/create_invoice_cardview"
        app:layout_constraintEnd_toStartOf="@+id/create_invoice_cardview"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/create_invoice_cardview">
    </android.support.v7.widget.CardView>

Top Right:

    <android.support.v7.widget.CardView
        android:id="@+id/create_invoice_cardview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="@dimen/button_gap_normal"
        android:layout_marginTop="185dp"
        android:layout_marginEnd="@dimen/margin_width_normal"
        android:layout_marginBottom="@dimen/button_gap_normal"
        app:layout_constraintBottom_toTopOf="@+id/add_single_cardview"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/capture_receipt_cardview"
        app:layout_constraintTop_toTopOf="parent">
   </android.support.v7.widget.CardView>

Bottom Horizontal:

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/add_single_cardview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="400dp"
        android:layout_marginBottom="68dp"
        app:layout_constraintBottom_toTopOf="@+id/navigation"
        app:layout_constraintEnd_toEndOf="@+id/create_invoice_cardview"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/capture_receipt_cardview"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1.0"
        app:layout_constraintVertical_weight="0">
    </android.support.v7.widget.CardView>
ghDev
  • 170
  • 1
  • 12

1 Answers1

0

What you are experiencing is brought by the difference in the idea of screen resolution vs pixel density. As mentioned here:

The pixel density is the number of pixels within a physical area of the screen and is referred to as dpi (dots per inch). This is different from the resolution, which is the total number of pixels on a screen.

In your case, Pixel has higher pixel density compared to that of Nexus 5.

To show you the difference, take this formula:

public int dpToPx(int dp) {
    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));     
}

Given your android:layout_marginBottom="68dp"

Number of pixels in your Nexus 5 phone:

102 = 68 * (240 / 160); // I am assuming the DPI is HIGH

Number of pixels in your Pixel phone:

136 = 68 * (320 / 160); // I am assuming the DPI is XHIGH   

Understanding this concept can go a long way in your Android programming career.

user1506104
  • 6,554
  • 4
  • 71
  • 89
  • Okay, I see that there are different pixel densities for the phones. But how can I use this to get the correct size? After messing around with it, I noticed the Nexus 5 is actually 480 and the Pixel is 420, giving values of 204 and 179 respectively. But this doesn't give the desired output. I have tried to modify the bottom margin programmatically, and it does change the size - however it is still not a generalized solution because I need to change it to different values for each screen. I.e changing it to the dpToPx value still varies in size greatly – ghDev Jul 07 '19 at 15:55
  • Dont convert your DP values to PX using the function i mentioned. Its just to show you the idea of DP. Always use DP values. – user1506104 Jul 07 '19 at 16:27
  • Okay, then how would you go about changing the size of elements so it is correct for each screen? Is this done using XML or programmatically? Any resources you can give help - I cannot seem to find this anywhere. – ghDev Jul 07 '19 at 16:35
  • What I am asking is if I have my bottom margin set to 68dp, why isn't it scaling automatically? Isn't this the point of dp? – ghDev Jul 07 '19 at 16:43
  • This is probably your two devices gets classified in the same bucket: xxhdpi. Obviously, they don't have the same pixel density. Thus the difference. Read more about it here: https://www.captechconsulting.com/blogs/understanding-density-independence-in-android – user1506104 Jul 07 '19 at 18:11