Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can make several different screen configurations map to a small set of layouts without having to duplicate portions of my layout XML?

My application shows either a one-pane UI or a two-pane UI depending on the screen configuration. On smaller screens, it should be one-pane both on portrait and landscape. On mid-sized screens (anything with a "smallest width" of 600dp and up), the landscape orientation accomodates the two-pane layout pretty well, but on portrait orientation, it should use the one-pane layout. On larger screens, it should use the two-pane layout on both orientations. I also want to support the 3.2+ style qualifiers (like sw600dp and sw720dp) as well as the older "size bucket" qualifier ("xlarge").

The most direct way to do this is create several different XML layout files, one for each configuration:

  • res/layout-sw600dp-land/main.xml
  • res/layout-sw600dp-port/main.xml
  • res/layout-sw720dp-land/main.xml
  • res/layout-sw720dp-port/main.xml
  • res/layout-xlarge-port/main.xml
  • res/layout-xlarge-land/main.xml
  • res/layout-port/main.xml
  • res/layout/main.xml

As a result, there's a lot of code duplication in these 8 XML files which essentially describe only two distinct layouts.

How can I do this without having to maintain all these duplicate XML files, which are a maintenance headache?

like image 480
Bruno Oliveira Avatar asked Apr 04 '12 21:04

Bruno Oliveira


1 Answers

You can use layout aliases. Rather than describing your layout directly in the XML files for each screen configuration, you should define your two layouts in two XML files called, say, "onepane.xml" and "twopanes.xml". These files go in res/layout.

Now, you have to map these layouts to your different screen configuration, and that's where the "layout alias" technique comes in handy. For each screen qualifier combination, create an XML file in res/values-X/layout.xml, where X is the qualifier combination. In that file, declare a layout resource that points to either @layout/onepane or @layout/twopanes, as appropriate:

res/values-sw600dp-land/layout.xml:

<resources>
  <item name="main" type="layout">@layout/twopanes</item>
</resources>

res/values-sw600dp-port/layout.xml:

<resources>
  <item name="main" type="layout">@layout/onepane</item>
</resources>

Do the same for your other configuration combinations, and that way you can accomplish what you're looking for: you can map your two layouts (onepane and twopane) to several different screen configurations without having to duplicate your layout.

For more information about this, take a look at the "Supporting Multiple Screens" lesson on Android Training: http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters

like image 98
Bruno Oliveira Avatar answered Oct 12 '22 07:10

Bruno Oliveira