5.3: Adaptive layouts
7 min readMar 2, 2019
Task 1: Support landscape orientation
1.1 Change to a GridLayoutManager
- Continue developing your version of the MaterialMe app, or download MaterialMe. If you decide to make a copy of the MaterialMe project to preserve the version from the previous practical, rename the copied version MaterialMe-Resource.
- Create a new resources file called
integers.xml
. To do this, open the res folder in the Project > Android pane, right-click (or Control-click) on the values folder, and select New > Values resource file.
- Name the file integers.xml and click OK.
- Create an integer constant between the
<resources>
tags calledgrid_column_count
and set it equal to 1:
<integer name="grid_column_count">1</integer>
- Create another values resource file, again called integers.xml; however, the name will be modified as you add resource qualifiers from the Available qualifiers pane. The resource qualifiers are used to label resource configurations for various situations.
- Select Orientation in the Available qualifiers pane, and press the >> symbol in the middle of the dialog to assign this qualifier.
- Change the Screen orientation menu to Landscape, and notice how the directory name
values-land
appears. This is the essence of resource qualifiers: the directory name tells Android when to use that specific layout file. In this case, that is when the phone is rotated to landscape mode. - Click OK to generate the new layout file.
- Copy the integer constant you created into this new resource file, but change the value to 2.
1.2 Modify MainActivity
- Open MainActivity, and add code to
onCreate()
to get the integer from theintegers.xml
resource file:
int gridColumnCount =
getResources().getInteger(R.integer.grid_column_count);
The Android runtime will take care of deciding which integers.xml
file to use, depending on the state of the device.
- Change the
LinearLayoutManager
for theRecyclerView
to aGridLayoutManager
, passing in the context and the newly created integer:
mRecyclerView.setLayoutManager(new
GridLayoutManager(this, gridColumnCount));
- Run the app and rotate the device. The number of columns changes automatically with the orientation of the device.
- Use the
gridColumnCount
variable to disable the swipe action (setswipeDirs
to zero) when there is more than one column:
int swipeDirs;
if(gridColumnCount > 1){
swipeDirs = 0;
} else {
swipeDirs = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
}
- Use
swipeDirs
in place of the swipe direction arguments (ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT
) forItemTouchHelper.SimpleCallback()
:
ItemTouchHelper helper = new ItemTouchHelper(new
ItemTouchHelper.SimpleCallback(ItemTouchHelper.LEFT |
ItemTouchHelper.RIGHT |
ItemTouchHelper.DOWN | ItemTouchHelper.UP,
swipeDirs) {
- Run the app and rotate the device. In landscape (horizontal) orientation, the user can no longer swipe to delete a card.
Task 2 : Support tablets
2.1 Adapt the layout to tablets
- Create an integers.xml resource file which uses the Smallest Screen Width qualifier with the value set to 600. Android uses this file whenever the app runs on a tablet.
- Copy the code from the integers.xml (land) file (it has a grid count of 2) and paste it in the new integers.xml (sw600dp) file.
- Create another integers.xml file that includes both the Smallest Screen Width qualifier set to 600, and the Orientation qualifier set to Landscape. Android uses the resulting
integers.xml (sw600dp-land)
file when the app runs on a tablet in landscape mode. - Copy the code from the integers.xml (land) file and paste it in the new integers.xml (sw600dp-land) file.
- Change the
grid_column_count
variable to 3 in the integers.xml (sw600dp-land) file.
- Run the app on a tablet or tablet emulator, and rotate it to landscape mode. The app should show three columns of cards, as shown in the first figure below. Rotate it to portrait mode, and the app should show two columns of cards, as shown in the second figure below. With these resource qualifier files, the app uses the screen real estate much more effectively.
2.2 Update the tablet list item styles
- Open styles.xml and add the following styles:
<style name="SportsDetailText"
parent="TextAppearance.AppCompat.Subhead"/>
<style name="SportsTitle"
parent="TextAppearance.AppCompat.Headline"/>
- Create a new
values
resource file called styles.xml that uses the Smallest Screen Width qualifier with a value of 600 for tablets.
- Copy all styles from the original styles.xml file into the new styles.xml (sw600dp) file.
- In styles.xml (sw600dp), change the
parent
of theSportsTitle
style to "TextAppearance.AppCompat.Display1":
<style name="SportsTitle"
parent="TextAppearance.AppCompat.Display1"/>
- The Android predefined
Display1
style uses thetextColorSecondary
value from the current theme (ThemeOverlay.AppCompat.Dark
), which in this case is a light gray color. The light gray color does not show up well on the banner images in your app. To correct this add an"android:textColor"
attribute to theSportsTitle
style and set it to "?android:textColorPrimary":
<style name="SportsTitle"
parent="TextAppearance.AppCompat.Display1">
<item name=
"android:textColor">?android:textColorPrimary</item>
- Change the
parent
ofSportsDetailText
style to "TextAppearance.AppCompat.Headline". - To update the style of the
TextView
elements, open list_item.xml, and change thestyle
attribute of thetitle
TextView
to @style/SportsTitle:
style="@style/SportsTitle"
- Change the
style
attribute of thenewsTitle
andsubTitle
TextView
elements to@style/SportsDetailText
. - Run your app on a tablet or tablet emulator. Each list item now has a larger text size on the tablet.
2.3 Update the tablet sports detail styles
- Add the following
style
in the styles.xml file for the detail title:
<style name="SportsDetailTitle"
parent="TextAppearance.AppCompat.Headline"/>
- Add the following
style
in the styles.xml (sw600dp) file for the detail title:
<style name="SportsDetailTitle"
parent="TextAppearance.AppCompat.Display3"/>
- Open activity_detail.xml, and change the
style
attribute of both thenewsTitleDetail
andsubTitleDetail
TextView elements to the newSportsDetailText
style you created in a previous step:
style="@style/SportsDetailText"
- In activity_detail.xml, change the
style
attribute of thetitleDetail
TextView
element to the newSportsDetailTitle
style you created:
style="@style/SportsDetailTitle"
- Run your app. All of the text is now larger on the tablet, which greatly improves the user experience of your application.
Task 3: Localize your app
3.1 Add a localized strings.xml file
- Create a new
values
resource file.
- Call the file strings.xml and select Locale from the list of available qualifiers. The Language and Specific Region Only panes appear.
- In the Language pane, select en: English.
- In the Specific Region Only pane, select US: United States and click OK. Android Studio creates a specific
values
directory in your project directories for the U.S. locale, calledvalues-en-rUS
. In the Project > Android pane, thestrings.xml
file in this directory appears as strings.xml (en-rUS) within the newly created strings.xml folder (with a U.S. flag icon).
- Copy all string resources of the generic strings.xmlfile (now located in the strings.xml folder) to strings.xml (en-rUS).
- In the generic strings.xml file, change the Soccer item in the
sports_titles array
to Football, and change the Soccer news text in thesports_info
array to Football news.
3.2 Run the app in different locales
- To switch the preferred language in your device or emulator, open the Settings app.
- Find the Languages & input settings in the Settings app, and choose Languages. Languages is the first choice on the Languages & input screen.
- For devices and emulators running a version of Android previous to Android 7, choose Language on the Languages & input screen, select a language and locale such as Français (France), and skip the following steps.
- For devices and emulators running Android 7 or newer, choose Languages on the Languages & input screen, select a language such as Français (France), and use the move icon on the right side of the Language preferences screen to drag Français (France) to the top of the list.
- Run the app with your device or emulator. In U.S. English, you should see “Soccer”.
- Switch to any language and locale other than U.S. English, and run the app again. You should then see “Football”.