1.2: Layouts, Views and Resources

Contents:

This chapter describes the screen's user interface layout and other resources you create for your app, and the code you would use to respond to a user's tap of a user interface element.

The model-view-presenter pattern

Linking an activity to a layout resource is an example of part of the model-view-presenter (MVP) architecture pattern. The MVP pattern is a well-established way to group app functions:

  • Views. Views are user interface elements that display data and respond to user actions. Every element of the screen is a view. The Android system provides many different kinds of views.
  • Presenters. Presenters connect the application's views to the model. They supply the views with data as specified by the model, and also provide the model with user input from the view.
  • Model. The model specifies the structure of the app's data and the code to access and manipulate the data. Some of the apps you create in the lessons work with models for accessing data. The Hello Toast app does not use a data model, but you can think of its logic — display a message, and increase a tap counter — as the model. The Model-View-Presenter (MVP) Architecture Pattern

Views

The UI consists of a hierarchy of objects called views — every element of the screen is a view. The View class represents the basic building block for all UI components, and the base class for classes that provide interactive UI components such as buttons, checkboxes, and text entry fields.

A view has a location, expressed as a pair of left and top coordinates, and two dimensions, expressed as a width and a height. The unit for location and dimensions is the device-independent pixel (dp).

The Android system provides hundreds of predefined views, including those that display:

You can define a view to appear on the screen and respond to a user tap. A view can also be defined to accept text input, or to be invisible until needed.

You can specify the views in XML layout resource files. Layout resources are written in XML and listed within the layout folder in the res folder in the Project: Android view.

View groups

Views can be grouped together inside a view group (ViewGroup), which acts as a container of views. The relationship is parent-child, in which the parent is a view group, and the child is a view or view group within the group. The following are common view groups:

  • ScrollView: A group that contains one other child view and enables scrolling the child view.
  • RecyclerView: A group that contains a list of other views or view groups and enables scrolling them by adding and removing views dynamically from the screen.

Layout view groups

The views for a screen are organized in a hierarchy. At the root of this hierarchy is a ViewGroup that contains the layout of the entire screen. The view group's child screens can be other views or other view groups as shown in the following figure. The View Hierarchy

In the above figure:

  1. The root view group.
  2. The first set of child views and view groups whose parent is the root.

Some view groups are designated as layouts because they organize child views in a specific way and are typically used as the root view group. Some examples of layouts are:

  • LinearLayout: A group of child views positioned and aligned horizontally or vertically.
  • RelativeLayout: A group of child views in which each view is positioned and aligned relative to other views within the view group. In other words, the positions of the child views can be described in relation to each other or to the parent view group.
  • ConstraintLayout: A group of child views using anchor points, edges, and guidelines to control how views are positioned relative to other elements in the layout. ConstraintLayout was designed to make it easy to drag and drop views in the layout editor.
  • TableLayout: A group of child views arranged into rows and columns.
  • AbsoluteLayout: A group that lets you specify exact locations (x/y coordinates) of its child views. Absolute layouts are less flexible and harder to maintain than other types of layouts without absolute positioning.
  • FrameLayout: A group of child views in a stack. FrameLayout is designed to block out an area on the screen to display one view. Child views are drawn in a stack, with the most recently added child on top. The size of the FrameLayout is the size of its largest child view.
  • GridLayout: A group that places its child screens in a rectangular grid that can be scrolled. Visual Representations of Layouts

Tip: Learn more about different layout types in Common Layout Objects.

A simple example of a layout with child views is the Hello Toast app in one of the early lessons. The view for the Hello Toast app appears in the figure below as a diagram of the layout file (activity_main.xml), along with a hierarchy diagram (top right) and a screenshot of the actual finished layout (bottom right). Layout Concept (left)

In the figure above:

  1. LinearLayout root layout, which contains all the child views, set to a vertical orientation.
  2. Button (button_toast) child view. As the first child view, it appears at the top in the linear layout.
  3. TextView (show_count) child view. As the second child view, it appears under the first child view in the linear layout.
  4. Button (button_count) child view. As the third child view, it appears under the second child view in the linear layout.

The view hierarchy can grow to be complex for an app that shows many views on a screen. It's important to understand the view hierarchy, as it affects whether views are visible and efficiently they are drawn.

Tip: You can explore the view hierarchy of your app using Hierarchy Viewer. It shows a tree view of the hierarchy and lets you analyze the performance of views on an Android device. Performance issues are covered in a subsequent chapter.

You define views in the layout editor, or by entering XML code. The layout editor shows a visual representation of XML code.

Using the layout editor

Use the layout editor to edit the layout file. You can drag and drop view objects into a graphical pane, and arrange, resize, and specify properties for them. You immediately see the effect of changes you make.

To use the layout editor, open the XML layout file. The layout editor appears with the Design tab at the bottom highlighted. (If the Text tab is highlighted and you see XML code, click the Design tab.) For the Empty Activity template, the layout is as shown in the figure below. The Layout Editor

In the figure above:

  1. XML layout file. The XML layout file, typically named activiy_main.xml file. Double-click it to open the layout editor.
  2. Palette of UI elements (views). The Palette pane provides a list of UI elements and layouts. Add an element or layout to the UI by dragging it into the design pane.
  3. Design toolbar. The design pane toolbar provides buttons to configure your layout appearance in the design pane and to edit the layout properties. See the figure below for details.

    Tip: Hover over each icon to view a tooltip that summarizes its function.

  4. Properties pane. The Properties pane provides property controls for the selected view.
  5. Property control. Property controls correspond to XML attributes. Shown in the figure is the Text property of the selected TextView, set to Hello World!.
  6. Design pane. Drag views from the Palette pane to the design pane to position them in the layout.
  7. Component Tree. The Component Tree pane shows the view hierarchy. Click a view or view group in this pane to select it. The figure shows the TextView selected.
  8. Design and Text tabs. Click Design to see the layout editor, or Text to see XML code.

The layout editor's design toolbar offers a row of buttons that let you configure the appearance of the layout: Design Toolbar

In the figure above:

  1. Design, Blueprint, and Both: Click the Design icon (first icon) to display a color preview of your layout. Click the Blueprint icon (middle icon) to show only outlines for each view. You can see both views side by side by clicking the third icon.
  2. Screen orientation: Click to rotate the device between landscape and portrait.
  3. Device type and size: Select the device type (phone/tablet, Android TV, or Android Wear) and screen configuration (size and density).
  4. API version: Select the version of Android on which to preview the layout.
  5. App theme: Select which UI theme to apply to the preview.
  6. Language: Select the language to show for your UI strings. This list displays only the languages available in the string resources.
  7. Layout Variants: Switch to one of the alternative layouts for this file, or create a new one.

The layout editor offers more features in the Design tab when you use a ConstraintLayout, including handles for defining constraints. A constraint is a connection or alignment to another view, to the parent layout, or to an invisible guideline. Each constraint appears as a line extending from a circular handle. Each view has a circular constraint handle in the middle of each side. After selecting a view in the Component Tree pane or clicking on it in the layout, the view also shows resizing handles on each corner. Constraint and Resizing Handles on Views

In the above figure:

  1. Resizing handle.
  2. Constraint line and handle. In the figure, the constraint aligns the left side of the view to the left side of the button.
  3. Baseline handle. The baseline handle aligns the text baseline of a view to the text baseline of another view.
  4. Constraint handle without a constraint line.

Using XML

It is sometimes quicker and easier to edit the XML code directly, especially when copying and pasting the code for similar views.

To view and edit the XML code, open the XML layout file. The layout editor appears with the Design tab at the bottom highlighted. Click the Text tab to see the XML code. The following shows an XML code snippet of a LinearLayout with a Button and a TextView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ... >

    <Button
        android:id="@+id/button_toast"
        android:layout_width="@dimen/my_view_width"
        android:layout_height="wrap_content"
        ... />

    <TextView
        android:id="@+id/show_count"
        android:layout_width="@dimen/my_view_width"
        android:layout_height="@dimen/counter_height"
        ... />
    ...
</LinearLayout>

XML attributes (view properties)

Views have properties that define where a view appears on the screen, its size, how the view relates to other views, and how it responds to user input. When defining views in XML, the properties are referred to as attributes.

For example, in the following XML description of a TextView, the android:id, android:layout_width, android:layout_height, android:background, are XML attributes that are translated automatically into the TextView's properties:

<TextView
       android:id="@+id/show_count"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="@color/myBackgroundColor"
       android:textStyle="bold"
       android:text="@string/count_initial_value"
/>

Attributes generally take this form:

android:attribute_name="value"

The attribute_name is the name of the attribute. The value is a string with the value for the attribute. For example:

android:textStyle="bold"

If the value is a resource, such as a color, the @ symbol specifies what kind of resource. For example:

android:background="@color/myBackgroundColor"

The background attribute is set to the color resource identified as myBackgroundColor, which is declared to be #FFF043. Color resources are described in "Style-related attributes" in this chapter.

Every view and view group supports its own variety of XML attributes. Some attributes are specific to a view (for example, TextView supports the textSize attribute), but these attributes are also inherited by any views that may extend the TextView class. Some are common to all views, because they are inherited from the root View class (like the android:id attribute). For descriptions of specific attributes, see the overview section of the View class documentation.

Identifying a view

To uniquely identify a view and reference it from your code, you must give it an id. The android:id attribute lets you specify a unique id — a resource identifier for a view.

For example:

android:id="@+id/button_count"

The "@+id/button_count" part of the above attribute creates a new id called button_count for the view. You use the plus (+) symbol to indicate that you are creating a new id.

Referencing a view

To refer to an existing resource identifier, omit the plus (+) symbol. For example, to refer to a view by its id in another attribute, such as android:layout_toLeftOf (described in the next section) to control the position of a view, you would use:

android:layout_toLeftOf="@id/show_count"

In the above attribute, "@id/show_count" refers to the view with the resource identifier show_count. The attribute positions the view to be "to the left of" the show_count view.

Positioning views

Some layout-related positioning attributes are required for a view, and automatically appear when you add the view to the XML layout, ready for you to add values.

LinearLayout positioning

For example, LinearLayout is required to have these attributes set:

The android:layout_width and android:layout_height attributes can take one of three values:

  • match_parent expands the view to fill its parent by width or height. When the LinearLayout is the root view, it expands to the size of the device screen. For a view within a root view group, it expands to the size of the parent view group.
  • wrap_content shrinks the view dimensions just big enough to enclose its content. (If there is no content, the view becomes invisible.)
  • Use a fixed number of dp (device-independent pixels) to specify a fixed size, adjusted for the screen size of the device. For example, 16dp means 16 device-independent pixels. Device-independent pixels and other dimensions are described in "Dimensions" in this chapter.

The android:orientation can be:

  • horizontal: Views are arranged from left to right.
  • vertical: Views are arranged from top to bottom.

Other layout-related attributes include:

  • Android:layout_gravity: This attribute is used with a view to control where the view is arranged within its parent view group. For example, the following attribute centers the view horizontally on the screen:
    android:layout_gravity="center_horizontal"
    
  • Padding is the space, measured in device-independent pixels, between the edges of the view and the view's content, as shown in the figure below. Padding

In the figure above:

  1. Padding is the space between the edges of the view (dashed lines) and the view's content (solid line). Padding is not the same as margin, which is the space from the edge of the view to its parent.

A view's size includes its padding. The following are commonly used padding attributes:

  • Android:padding: Sets the padding of all four edges.
  • android:paddingTop: Sets the padding of the top edge.
  • android:paddingBottom: Sets the padding of the bottom edge.
  • android:paddingLeft: Sets the padding of the left edge.
  • android:paddingRight: Sets the padding of the right edge.
  • android:paddingStart: Sets the padding of the start of the view; used in place of the above, especially with views that are long and narrow.
  • android:paddingEnd: Sets the padding, in pixels, of the end edge; used along with android:paddingStart.

Tip: To see all of the XML attributes for a LinearLayout, see the Summary section of the LinearLayout reference in the Developer Guide. Other root layouts, such as RelativeLayout and AbsoluteLayout, list their XML attributes in the Summary sections.

RelativeLayout Positioning

Another useful view group for layout is RelativeLayout, which you can use to position child views relative to each other or to the parent. The attributes you can use with RelativeLayout include the following:

For a complete list of attributes for views in a RelativeLayout, see RelativeLayout.LayoutParams.

You specify style attributes to customize the view's appearance. Views that don't have style attributes, such as android:textColor, android:textSize, and android:background, take on the styles defined in the app's theme.

The following are style-related attributes used in the XML layout example in the previous section:

  • Android:background: Specifies a color or drawable resource to use as the background.
  • android:text: Specifies text to display in the view.
  • android:textColor: Specifies the text color.
  • android:textSize: Specifies the text size.
  • android:textStyle: Specifies the text style, such as bold.

Resource files

Resource files are a way of separating static values from code so that you don't have to change the code itself to change the values. You can store all the strings, layouts, dimensions, colors, styles, and menu text separately in resource files.

Resource files are stored in folders located in the res folder, including:

  • drawable: For images and icons
  • layout: For layout resource files
  • menu: For menu items
  • mipmap: For pre-calculated, optimized collections of app icons used by the Launcher
  • values: For colors, dimensions, strings, and styles (theme attributes)

The syntax to reference a resource in an XML layout is as follows:

@package_name:resource_type/resource_name
  • The package_name is the name of the package in which the resource is located. This is not required when referencing resources from the same package — that is, stored in the res folder of your project.
  • resource_type is the R subclass for the resource type. See Resource Types for more information about each resource type and how to reference them.
  • resource_name is either the resource filename without the extension, or the android:name attribute value in the XML element.

For example, the following XML layout statement sets the android:text attribute to a string resource:

android:text="@string/button_label_toast"
  • The resource_type is string.
  • The resource_name is button_label_toast.
  • There is no need for a package_name because the resource is stored in the project (in the strings.xml file).

Another example: this XML layout statement sets the android:background attribute to a color resource, and since the resource is defined in the project (in the colors.xml file), the package_name is not specified:

android:background="@color/colorPrimary"

In the following example, the XML layout statement sets the android:textColor attribute to a color resource. However, the resource is not defined in the project but supplied by Android, so the package_name android must also be specified, followed by a colon:

android:textColor="@android:color/white"

Tip: For more information about accessing resources from code, see Accessing Resources. For Android color constants, see the Android standard R.color resources.

Values resource files

Keeping values such as strings and colors in separate resource files makes it easier to manage them, especially if you use them more than once in your layouts.

For example, it is essential to keep strings in a separate resource file for translating and localizing your app, so that you can create a string resource file for each language without changing your code. Resource files for images, colors, dimensions, and other attributes are handy for developing an app for different device screen sizes and orientations.

Strings

String resources are located in the strings.xml file in the values folder inside the res folder when using the Project: Android view. You can edit this file directly by opening it:

<resources>
    <string name="app_name">Hello Toast</string>
    <string name="button_label_count">Count</string>
    <string name="button_label_toast">Toast</string>
    <string name="count_initial_value">0</string>
</resources>

The name (for example, button_label_count) is the resource name you use in your XML code, as in the following attribute:

android:text="@string/button_label_count"

The string value of this name is the word (Count) enclosed within the <string></string> tags (you don't use quotation marks unless the quotation marks should be part of the string value.)

Extracting strings to resources

You should also extract hard-coded strings in an XML layout file to string resources. To extract a hard-coded string in an XML layout, follow these steps (refer to the figure): Extracting a String Resource Naming the String Resource

  1. Click on the hard-coded string, and press Alt-Enter in Windows, or Option-Return on Mac OS X.
  2. Select Extract string resource.
  3. Edit the Resource name for the string value.

You can then use the resource name in your XML code. Use the expression "@string/resource_name" (including quotation marks) to refer to the string resource:

android:text="@string/button_label_count"

Colors

Color resources are located in the colors.xml file in the values folder inside the res folder when using the Project: Android view. You can edit this file directly:

<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="myBackgroundColor">#FFF043</color>
</resources>

The name (for example, colorPrimary) is the resource name you use in your XML code:

android:textColor="@color/colorPrimary"

The color value of this name is the hexadecimal color value (#3F51B5) enclosed within the <color></color> tags. The hexadecimal value specifies red, green, and blue (RGB) values. The value always begins with a pound (#) character, followed by the Alpha-Red-Green-Blue information. For example, the hexadecimal value for black is #000000, while the hexadecimal value for a variant of sky blue is #559fe3. Base color values are listed in the Color class documentation.

The colorPrimary color is one of the predefined base colors and is used for the app bar. In a production app, you could, for example, customize this to fit your brand. Using the base colors for other UI elements creates a uniform UI.

Tip: For the material design specification for Android colors, see Style and Using the Material Theme. For common color hexadecimal values, see Color Hex Color Codes. For Android color constants, see the Android standard R.color resources.

You can see a small block of the color choice in the left margin next to the color resource declaration in colors.xml, and also in the left margin next to the attribute that uses the resource name in the layout XML file. Color Blocks in the Resource File Color Block in the Layout File

Tip: To see the color in a popup, turn on the Autopopup documentation feature. Choose Android Studio > Preferences > Editor > General > Code Completion, and check the "Autopopup documentation in (ms)" option. You can then hover your cursor over a color resource name to see the color.

Dimensions

Dimensions should be separated from the code to make them easier to manage, especially if you need to adjust your layout for different device resolutions. It also makes it easy to have consistent sizing for views, and to change the size of multiple views by changing one dimension resource.

Dimension resources are located in a dimens.xml file in the values folder inside the res folder when using the Project: Android view. The dimens.xml shown in the view can be a folder holding more than one dimens.xml file for different device resolutions. For example, the app created from the Empty Activity template provides a second dimens.xml file for 820dp.

You can edit this file directly by opening it:

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="my_view_width">300dp</dimen>
    <dimen name="count_text_size">200sp</dimen>
    <dimen name="counter_height">300dp</dimen>
</resources>

The name (for example, activity_horizontal_margin) is the resource name you use in the XML code:

android:paddingLeft="@dimen/activity_horizontal_margin"

The value of this name is the measurement (16dp) enclosed within the <dimen></dimen> tags.

You can extract dimensions in the same way as strings::

  1. Click on the hard-coded dimension, and press Alt-Enter in Windows, or press Option-Return on Mac OS X.
  2. Select Extract dimension resource.
  3. Edit the Resource name for the dimension value.

Device-independent pixels (dp) are independent of screen resolution. For example, 10px (10 fixed pixels) will look a lot smaller on a higher resolution screen, but Android will scale 10dp (10 device-independent pixels) to look right on different resolution screens. Text sizes can also be set to look right on different resolution screens using scaled-pixel (sp) sizes.

Tip: For more information about dp and sp units, see Supporting Different Densities.

Styles

A style is a resource that specifies common attributes such as height, padding, font color, font size, background color. Styles are meant for attributes that modify the look of the view.

Styles are defined in the styles.xml file in the values folder inside the res folder when using the Project: Android view. You can edit this file directly. Styles are covered in a later chapter, along with the Material Design Specification.

Other resource files

Android Studio defines other resources that are covered in other chapters:

  • Images and icons. The drawable folder provides icon and image resources. If your app does not have a drawable folder, you can manually create it inside the res folder. For more information about drawable resources, see Drawable Resources in the App Resources section of the Android Developer Guide.
  • Optimized icons. The mipmap folder typically contains pre-calculated, optimized collections of app icons used by the Launcher. Expand the folder to see that versions of icons are stored as resources for different screen densities.
  • Menus. You can use an XML resource file to define menu items and store them in your project in the menu folder. Menus are described in a later chapter.

Responding to view clicks

A click event occurs when the user taps or clicks a clickable view, such as a Button, ImageButton, ImageView (tapping or clicking the image), or FloatingActionButton.

The model-view-presenter pattern is useful for understanding how to respond to view clicks. When an event occurs with a view, the presenter code performs an action that affects the model code. In order to make this pattern work, you have to:

  • Write a Java method that performs the specific action, which is determined by the logic of the model code — that is, the action depends on what you want the app to do when this event occurs. This is typically referred to as an event handler.
  • Associate this event handler method to the view, so that the method executes when the event occurs.

The onClick attribute

Android Studio provides a shortcut for setting up a clickable view, and for associating an event handler with the view: use the android:onClick attribute with the clickable view's element in the XML layout.

For example, the following XML expression in the layout file for a Button sets showToast() as the event handler:

android:onClick="showToast"

When the button is tapped, its android:onClick attribute calls the showToast() method.

Write the event handler, such as showToast() referenced in the XML code above, to call other methods that implement the app's model logic:

public void showToast(View view) {
        // Do something in response to the button click.
}

In order to work with the android:onClick attribute, the showToast() method must be public, return void, and require a view parameter in order to know which view called the method.

Android Studio provides a shortcut for creating an event handler stub (a placeholder for the method that you can fill in later) in the Java code for the activity associated with the XML layout. Follow these steps:

  1. Inside the XML layout file (such as activity_main.xml), click the method name in the android:onClick attribute statement.
  2. Press Alt-Enter in Windows or Option-Return in Mac OS X, and select Create onClick event handler.
  3. Choose the activity associated with the layout file (such as MainActivity) and click OK. This creates a placeholder method stub in MainActivity.java.

Updating views

To update a view's contents, such as replacing the text in a TextView, your code must first instantiate an object from the view. Your code can then update the object, thereby updating the view.

To refer to the view in your code, use the findViewById() method of the View class, which looks for a view based on the resource id. For example, the following statement sets mShowCount to be the TextView with the resource id show_count:

mShowCount = (TextView) findViewById(R.id.show_count);

From this point on, your code can use mShowCount to represent the TextView, so that when you update mShowCount, the view is updated.

For example, when the following button with the android:onClick attribute is tapped, onClick calls the countUp() method:

android:onClick="countUp"

You can implement countUp() to increment the count, convert the count to a string, and set the string as the text for the mShowCount object:

public void countUp(View view) {
        mCount++;
        if (mShowCount != null)
            mShowCount.setText(Integer.toString(mCount));
}

Since you had already associated mShowCount with the TextView for displaying the count, the mShowCount.setText() method updates the text view on the screen.

The related exercises and practical documentation is in Android Developer Fundamentals: Practicals.

Learn more

results matching ""

    No results matching ""