Customizing a layout for different devices


#1

I am writing my first app. My first layout fragment displays a title, three buttons, and one ImageButton. I put various sizes in the res/values/dimens.xml file. I then tried to determine what to name the other values-xxxxx directories for different screen sizes, so I could modify the dimens.xml file for each size. I want the text size for the buttons to be smaller on smaller devices, and for the ImageButton’s margin to be different as well so it displays between the 3rd button and bottom of the screen.

The ImageButton would disappear on devices with a height of 320.

So, I created [color=#BF0000]values-h320dp[/color]. But it did not use the dimens.xml file I put there. I tried others, like [color=#BF0000]values-h200p[/color] and [color=#BF0000]values-h400dp[/color], hoping the smaller devices would use the h200dp one and the rest would use the h400dp one. Nope. sw240dp didn’t work either.

Finally, I created [color=#BF0000]values-ldpi[/color] and [color=#BF0000]values-mdpi[/color]. These work, and the display now works on the small and regular size devices. (I will deal with tablets and such later). So does values-small BTW.

Since the book says to use the [color=#0000BF]Discrete screen dimension qualifiers[/color] , and doesn’t mention doing it by screen density, I feel like this is wrong.

I also think that being concerned with those small screens may be wrong, if they are used by devices that are before the min-SDK of 8.

And, I don’t like using a hard coded value to make that ImageButton go well below the 3rd button.

Here are the files, in case it helps:

Layout:

[code]

<TextView
	android:id="@+id/textView1"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:gravity="center"
	android:shadowColor="@color/text_shadow"
	android:shadowDx="9"
	android:shadowDy="9"
	android:shadowRadius="10"
	android:text="@string/page1_title"
	android:textColor="@color/title_text"
	android:textSize="@dimen/title_text_size"
	android:textStyle="bold" />

<Button
	android:id="@+id/main_Button_makepotions"
	style="@style/MainButton"
	android:text="@string/make_potions" />

<Button
	android:id="@+id/main_Button_recipebook"
	style="@style/MainButton"
	android:text="@string/recipe_book" />

<Button
	android:id="@+id/main_Button_database"
	style="@style/MainButton"
	android:text="@string/Database" />

<ImageButton
	android:id="@+id/main_imageButton_info"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_gravity="bottom|center_horizontal"
	android:layout_marginTop="@dimen/help_button_pad_top"
	android:contentDescription="@string/main_info_button"
	android:scaleType="centerInside"
	android:src="@android:drawable/ic_dialog_info" />
[/code]

The default dimens.xml

[code]

<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="button_text_size">24sp</dimen>
<dimen name="button_text_size_landscape">12sp</dimen>
<dimen name="button_margin_landscape">12dp</dimen>
<dimen name="title_text_size">44sp</dimen>
<dimen name="button_margin_top">24dp</dimen>
<dimen name="help_button_pad_top">48dp</dimen>

[/code]

Thanks!!


#2

One other thing, is the landscape view. I want the buttons to display horizontally, be spaced well, and be the same size regardless of the text. How do I do that?

I put them in a LinearLayout:

[code]

	<Button
		android:id="@+id/main_Button_makepotions"
		style="@style/MainButtonLandscape"
		android:text="@string/make_potions" />

	<Button
		android:id="@+id/main_Button_recipebook"
		style="@style/MainButtonLandscape"
		android:text="@string/recipe_book" />

	<Button
		android:id="@+id/main_Button_database"
		style="@style/MainButtonLandscape"
		android:text="@string/Database" />

</LinearLayout>[/code]

I have played with weight and gravity settings, but the buttons aren’t the same size, and Eclipse complains if I put those settings on the buttons too.

Thanks.


#3

Can you please help with this?

This link shows that small devices (320x240, ldpi) are used by API 8, which is the minimum the book supports in all of the projects. The Android tutorials says to use -small for pre 3.2 and -sw?? for 3.2+. They only show -ldpi and such being used for the drawable- folders, not layout- and values-.

But you say using -small is obsolete. I would love to see the folders you would create to support the devices in that link, and how you would design for different screen sizes, densities, and APIs.

Thanks.


#4

1- The issue with the explicit qualifiers (swXXXdp, hXXXdp, etc) is that they’re only available on Android 3.2 and higher. We strongly recommend using them when they are available (which they are, for almost all relevant larger devices), but for pre-3.2 devices one has no choice other than to use the -small, -medium, and -large qualifiers.

2- As for your buttons, I’d like to know some specifics. A picture might actually help a lot here - e.g., do you want the individual buttons to expand with the device size? Or do you want their size fixed entirely?

I can say for sure that you won’t want to use wrap_content for your button widths. That will always make your button size dependent on the text each button contains, no matter what you do.


#5

Thanks!

I decided that I want the buttons to have fixed widths so they have the same size in portrait (they are in a vertical LinearLayout and don’t just span the screen on large screens) and landscape (they are in a horizontal LinearLayout and I want them to have the same width regardless of text).

Here is what I have in the styles.xml:

[code]
match_parent
wrap_content
#000040
@dimen/button_text_size
@dimen/button_margin_top
@drawable/button_shape_shadow

<style name="MainButtonLandscape" parent="MainButton">
	<item name="android:layout_width">@dimen/main_button_length_hor</item>
	<item name="android:layout_gravity">center_horizontal</item>
	<item name="android:layout_marginLeft">@dimen/button_margin_landscape</item>
	<item name="android:layout_marginRight">@dimen/button_margin_landscape</item>
	<item name="android:textSize">@dimen/button_text_size_landscape</item>
	<item name="android:layout_marginTop">0dp</item>
</style>[/code]

values-mdpi/dimen.xml

<dimen name="button_text_size">36sp</dimen> <dimen name="button_text_size_landscape">24sp</dimen> <dimen name="button_margin_landscape">12dp</dimen> <dimen name="main_button_length_hor">240dp</dimen> <dimen name="button_margin_top">16dp</dimen> <dimen name="button_margin_left">44dp</dimen> <dimen name="button_margin_right">44dp</dimen>

values-ldpi/dimen.xml

<dimen name="button_text_size">24sp</dimen> <dimen name="button_text_size_landscape">16sp</dimen> <dimen name="button_margin_landscape">12dp</dimen> <dimen name="button_margin_left">44dp</dimen> <dimen name="button_margin_right">44dp</dimen> <dimen name="main_button_length_hor">100dp</dimen> <dimen name="button_margin_top">16dp</dimen>

However, I am wondering if it’s better to have different “layout-” folders to customize the display than to put the sizes in the dimen.xml files that are based on density.

To what extent should we concern ourselves with screen size versus screen density?

Thank you!


#6

We usually try not to worry about density at all, except when dealing with image assets. If you use dp, those will scale with density, so you should be fine omitting density specific dimens.xml values. (Having a different dimens for each density will get really hairy if you find yourself needing to change dimensions in different orientations or screen sizes!)

We instead deal solely in screen size. And we do it by changing our interface in broad ways to fit broad categories of devices. E.g., we typically have one layout that is intended to adjust to all phone-sized devices, and another that includes extra elements for tablet-sized devices. We may also use dimens values to adjust spacing and/or styling on larger or smaller screens.

One thing I’d point out is that I typically prefer not to have layout parameters defined in my styles. This can save typing, but can be very confusing - if the layout params are in the style, it’s impossible to know how a layout file will be displayed on screen just from looking at it.


#7

Aha! Makes sense. I will need to rework it to use “layout-” folders and keep sizes in the layouts and only use styles.xml for colors and such. I saw the dimen.xml file and though it would be good to use.

Thank you for helping me understand that!