3

Well, unfortunately i'm bumping on different screen sizes when my app is already finished and fully functional.

I found thousand answers about different devices/resolutions/dpi implementation and i tried to learn something from each one.

My goal is to NOT use different density folders but to resize/repositioning already existing pictures for each layout resolution/dpi. A little blur in pictures caused by resizing is at this time not important for me. My app is a school project and i need to start it within few days.

My idea is to create a giant set of layout folders like:

layout-normal-mdpi    
layout-normal-hdpi
layout-normal-xhdpi
layout-normal-xxhdpi
layout-normal-xxxhdpi
layout-large-mdpi
layout-large-hdpi
layout-large-xhdpi
layout-large-xxhdpi
layout-large-xxxhdpi
layout-xlarge-mdpi
layout-xlarge-hdpi
layout-xlarge-xhdpi
layout-xlarge-xxhdpi
layout-xlarge-xxxhdpi

Copy/Paste my activities there and to set each activity object with a desired DP value to make the app usable/viewable on most devices.

After this i will create as more as possible virtual devices to test and edit graphics correctly.

Well again, what i'm losing by this way (except for quality DPI resolution)?

Have you a better idea to make my app compatible with most devices?

My app is targeting Tablets in most part and i would like to make it compatible to phones over 4inch as well.

Last question:

using the density value like me:

layout-normal -hdpi

is a good pratice? will it be implemented in future android releases? Or is better to avoid usind DPI values like:

layout-normal

Thanks a lot for any help.

This is a screenshot of my virtual device created as Galaxy S7 Edge. It loads itself the layout-normal-xxxhdpi layout.

enter image description here

WizardingStudios
  • 554
  • 2
  • 7
  • 22
  • 1
    This is one of the best Android layout related SO posts I've seen in a while for complex layouts requiring "device specific" view sizes and positions. Leodev's answer would really cut down bloated res folders and should be part of the protocol for creating layout folders that need to use the swXXXdp method. – whyoz Apr 24 '17 at 17:30

3 Answers3

3

I suggest you not to create all this layout, but to create different dimens.xml files, in this way you have to create only one layout, with one size attribute for each view, that Android takes automatically based on device screen dimensions. Here is an example:

LAYOUT:

<ImageView
        android:id="@+id/image_cat"
        android:layout_width="@dimen/width_category_image_carousel"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:foregroundGravity="center_horizontal|bottom" />

FILE DIMENS.XML for sw300dp (this indicate that smallest width, regardless orientation, must be 300dp)

<resources >
    <dimen name="width_category_image_carousel">220dp</dimen>
</resources>

You have to create more files dimens.xml inside values directory in resources directory, based on different size screens you want to support. You can find more information about how to define different dimens here: https://developer.android.com/guide/practices/screens_support.html#NewQualifiers

leodev
  • 208
  • 4
  • 13
  • Hi @LG89, this answer sound very interesting for me! Anyway i have some questions: Take as for example a dimension file like: **res/values-sw720dp/dimens.xml** This will works nice on a device like 720x1280 but will result exatcly the same graphic in another device like 1400x900? Will the same graphics be resized automatically? Or i need necessarily to create a **res/values-sw900dp/dimens.xml**? – WizardingStudios Feb 23 '17 at 22:06
  • Well, first of all, using dp how unit measure will create different size in devices with different density pixel, so basically, the answer to your first question is no, it will not result the same graphic in 720x1280 and 1400x900, but not cause to dimens file, but for the dp definition. Then, if you mean that the dimension value will be the same in 720x1280 and 1400x900, YES, for example a 120dp value will be for first device will be the same for the second, so if you want to have a better layout you have to create other dimension files – leodev Feb 23 '17 at 22:48
  • thanks again, i'm implementing your answer and the result it's so good... but... I'm testing on Android Studio, virtual device is Galaxy S7 Edge, screen size is 1440x2560. I tried creating a values folder named **res/values-sw1400dp/dimens.xml** but the editor does not changed anything. I tried also **res/values-sw1000dp/dimens.xml** and **res/values-sw720dp/dimens.xml** same result again. Finally i tried **res/values-xxxhdpi/dimens.xml** and it works perfectly! I miss something? I don't want to lose the possibility to have a lot more dimen with the SW method... – WizardingStudios Feb 23 '17 at 22:54
  • tried also sw300dp, same result, the editor does not see it. – WizardingStudios Feb 23 '17 at 23:15
  • edit: sw300dp works as expected...needed a refresh... Why i cannot put, as 4 example, 720dp on that phone which is over 1400dp? – WizardingStudios Feb 23 '17 at 23:30
  • I think that you confused px and dp. 1440x2560 are PIXELS, but this device has 360x640dp that is different! So the file sw1400dp is useless! Take a look at this table to have a clear idea of measures in real devices. https://material.io/devices/ – leodev Feb 23 '17 at 23:41
  • :-/ You're right my friend. Thanks again for the help, your solution is the most elegant and the less resources consuming. Works as expected and i like it so much! – WizardingStudios Feb 24 '17 at 07:22
  • Last question, please: in your code there is **android:layout_weight="2"** . As i think is this unnecessary, i'm right? – WizardingStudios Feb 24 '17 at 07:26
  • Oh yes, I just took a bit of code from a project I had..but just to show you the use of width attribute with dimens files ;) Glad I helped you! – leodev Feb 24 '17 at 09:15
0

Well again, what i'm losing by this way (except for quality DPI resolution)?

The layout can be totally different. Some view can be out of screen. Some text may not be containing in their layouts. And of course ImageViewswill be stretched as hell.

Have you a better idea to make my app compatible with most devices?

Yes. You can build your layouts based on the attribute layout_weight.

https://developer.android.com/guide/topics/ui/layout/linear.html

This work for LinearLayout but also with RelativeLayout in a slighty different way. The goal of this attribute is to gave to each view inside a layout some percentage of the total size.

Exemple of use.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:weightSum="5">

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="1" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="3"
        android:text="2" />

    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="3" />

    </LinearLayout>

This way you can build UI wich adapt themselve to each screen size and density.

But be carefull, there is warning about using this attribute. If you use nested layouts with layout_weight attributes, performance of rendering your views will decrease significantly .

Why are nested weights bad for performance? Alternatives?

Community
  • 1
  • 1
Cedric Franck
  • 526
  • 4
  • 9
0

Assuming it's the quality of the images you're concerned about because you resize them depending on space available I would do the following:

  1. I would put these images in res/drawable-nodpi e.g. image1_360.png, image1_540.png, image1_720.png, image1_1080.png if you have an image that should fit the device width.
  2. In res/values I would create a drawables.xml file with:

    <drawable name="image1">@drawable/image1_360</drawable>
    

In values-hdpi I would replace that image with

    <drawable name="image1">@drawable/image1_540</drawable>

and similarly for xhdpi and xxhdpi

  1. In values-w600dp I would replace that image with

    <drawable name="image1">@drawable/image1_540</drawable>
    

and similarly for the higher density buckets

  1. In values-w720dp I would replace that image with

    <drawable name="image1">@drawable/image1_720</drawable>
    

and for values-w720dp-hdpi with

    <drawable name="image1">@drawable/image1_1080</drawable>
  1. In values-w1000dp I would replace that image with

    <drawable name="image1">@drawable/image1_1080</drawable>
    

This might vary depending on your actual needs but the idea is to use values folder for different screen sizes & density bucket combinations and reference the drawables using the drawable XML tag.

Piotr Zawadzki
  • 1,678
  • 1
  • 18
  • 24
  • Thanks Piotr, as i think this is the same thing as to create various drawable folders, one for each DPI value. With this answer i have to store a large amount of pictures inside my app. – WizardingStudios Feb 23 '17 at 21:51
  • I thought the issue was that you had to store the drawables for each DPI bucket x 3 (phone, small & large tablets)? This solution allows you to limit the number actual drawables used. – Piotr Zawadzki Feb 24 '17 at 06:50
  • yes i should limit to Phone, small and large tablet. Anyway the accepted answer require only 1 picture for each dimension. Sometime the resize method should give ugly results, In next project i will start with sw900dp pictures directly to limit resize graphical issues. Many many thanks anyway. – WizardingStudios Feb 24 '17 at 15:08