4

After reading this (http://developer.android.com/guide/practices/screens_support.html), I have developed an entire app using the dp unit inside the xml files. However, when I test the app in different screens, the layouts are either too big or too small.

I thought the dp unit would fix that for me. Why didn't it? I do not want to use the weight attribute since everything is already done.

One xml layout:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="140dp"
    android:src="@drawable/logo3"
    android:scaleType="centerCrop"

    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/select_level"
    android:textColor="#4cb122"
    android:layout_gravity="center_horizontal"
    android:gravity="center_horizontal"
    android:textSize="20dp"
    android:layout_marginTop="20dp"
    />

<Button
    android:background="@drawable/red_button"
    android:layout_width="200dp"
    android:layout_height="55dp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="25dp"
    android:text="@string/easy"
    android:textSize="15dp"
    android:onClick="playEasy"
    style="custom_button"
    />

<Button
    android:background="@drawable/green_button"
    android:layout_width="200dp"
    android:layout_height="55dp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="10dp"
    android:text="@string/medium"
    android:textSize="15dp"
    android:onClick="playMedium"
    style="custom_button"
    />

<Button
    android:background="@drawable/blue_button"
    android:layout_width="200dp"
    android:layout_height="55dp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="10dp"
    android:textSize="15dp"
    android:text="@string/unbeatable"
    android:onClick="playUnbeatable"
    style="custom_button"
    />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:layout_marginTop="113dp"
    android:textSize="15dp"
    android:textColor="@color/secondTextColor"
    android:text="@string/developed_by"
    />

What could I do? Thanks!

João Marcos
  • 75
  • 1
  • 6
  • Please provide a [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve) demonstrating your problem. In this case, it would include the layout files, dimension resource files (if you are using those), and screenshots showing your results. – CommonsWare Feb 06 '16 at 19:00
  • 1. You should provide (one of) the layouts in question and maybe a screenshot of your problem. 2. `dp` is used to ensure same sizes on different screens, it does not 'scale' the layout itself. – David Medenjak Feb 06 '16 at 19:00
  • It ensures same size? So that's not what I need! How do I code something that will be automatically scaled? – João Marcos Feb 06 '16 at 19:07
  • I'm just using one image, so I don't think I need to have multiple images as drawable resources. How do I scale simple TextViews and Buttons? – João Marcos Feb 06 '16 at 19:12
  • You should use 'sp' instead of 'dp' for text size. Read - http://stackoverflow.com/questions/11638691/android-sp-vs-dp-texts-what-would-adjust-the-scale-and-what-is-the-philosoph – Swas_99 Feb 06 '16 at 20:40

1 Answers1

5

Using dp for dimensions is not a truly one size fits all solution for this problem.

Note that you should use layout weight when possible, and in general one dp value should work for all screen sizes. However, sometimes you will run in to a edge case that causes problems, and you just need to do something to make it work (For example I had to use this technique for positioning a badge on a tab in a TabLayout correctly for all screen sizes).

What I do to get around it is to put a dimens.xml file for each supported screen size:

  • res/values-small/dimens.xml

  • res/values-normal/dimens.xml

  • res/values-large/dimens.xml

  • res/values-xlarge/dimens.xml

You can use other qualifiers as well to target tablets if that is needed, see here for a guide to configuration qualifier names.

Then, specify each dimension for each screen size qualifier in each file (note that this only needs to be done for the dimension values that are causing problems on very large or very small screens).

For example in res/values-large/dimens.xml you might have this:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <dimen name="image_view_height">140dp</dimen>

</resources>

Then in res/values-small/dimens.xml you might have this to make it fit on the smaller screens:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <dimen name="image_view_height">96dp</dimen>

</resources>

Then, in your layout, reference it with @dimen/your_dimens_id, and the framework will choose the correct one to take for the screen size of the device:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="@dimen/image_view_height"
    android:src="@drawable/logo3"
    android:scaleType="centerCrop"

    />
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • That works indeed! So, giving that I'll need to do everything again, do you think it's best to do what you just said or to use weight attributes? Thanks! – João Marcos Feb 06 '16 at 19:30
  • @JoãoMarcos I would say use weight attributes where you can get away with it and make it work easily, and use the above method when you absolutely must use dp. – Daniel Nugent Feb 06 '16 at 19:32
  • 2
    This seems wrong. The entire point of `dp` units is that you **don't** care about screen density, so why would you make alternate dimensions based on screen density qualifiers? It makes more sense to have different dimensions for screen **size** qualifiers (e.g. `-sw600`). Tablets tend to have a larger screen **size** but a smaller screen **density**, so I would use `dp` units but maybe specify a larger dimension for something when it appears on a tablet screen. – Karakuri Feb 06 '16 at 19:33
  • 1
    That is a good point. I suppose this is a "quick and dirty" way of doing it, and you're right that it doesn't really make sense to specify different dp for different densities. It did work to overcome this issue for me though, even if it's an ugly solution! Also I think you're right that defining screen size qualifiers would make more sense, just edited the answer. – Daniel Nugent Feb 06 '16 at 20:01
  • I tried using weight attributes, but it doesn't work because Android does not recognize weights within nested layouts. But that's exactly what I need: nested layouts. This seems to be such a crucial problem every developer has had to overcome: scaling for different screens. Why don't I find working solutions? – João Marcos Feb 12 '16 at 16:33