What is the LayoutInflater in Android

3 layout I

Status: 07/21/2018

This chapter deals exclusively with the visual, i.e. the graphical user interface. How do you put the arrangement, so that layout of the various components (text fields, buttons, sliders, etc.)?

What is the big challenge with all graphic interfaces: How do I deal with the fact that there are screens of different sizes and that the screen can be oriented either horizontally (landscape) or vertically (portrait)?

3.1.1 Objects

In object-oriented programming languages ​​are visible graphic components such as buttons and text fields Java objects, that is, instances of Java classes. This is intuitive from the programmer's point of view and good design from the point of view of software technology.

From XML to Java (inflate)

We know from the previous module that our components and layouts are created using a XML file (e.g. activity_main.xml). How do you bring this XML together with Java?

The answer is in the file. There we see:

The relevant here is the call from. In this line Java first gets the ID of the layout file with the help of class R, then gets this file and converts the XML into Java objects.

This process is also called inflate (English for inflate). With the help of the class, you can also programmatically transfer any XML layout to Java, as we will see elsewhere. Here the process is included in the method.

Invisible layout objects

It is important that it is too invisible Objects there that are pure Layout function to have. These objects serve as Containerthat contain other objects (e.g. text fields and buttons) and determine where these objects are to be displayed.

An example is a layout object of the type that can contain various visible components and simply arranges them along a line. Here e.g. once vertically, once horizontally:

These layout objects can contain both visible and invisible components.

3.1.2 Tree structure

All visible Objects (e.g. text fields, buttons) are instances of subclasses of the class. Such components will too Widgets called.

All non-visible (Layout) objects are instances of subclasses of the class. Since a layout object can also contain other layout objects, we can create complex layouts by nesting them.

Here you can simply see a vertical linear layout (purple) and, contained therein, a horizontal linear layout (yellow).

A layout therefore consists of a nesting of Views and ViewGroups. Together it results in one Tree structure:

For performance reasons, Google recommends keeping the nesting depth as small as possible.

A

  • ViewGroup: contains either Views or ViewGroups
  • View: stands at the "end" of a branch and cannot contain anything else

There is always a ViewGroup at the top of the tree shown. This is also called that Root layout (English root layout).

Two very common layouts are LinearLayout and RelativeLayout. A further layout has recently been introduced as the Layout used: that ConstraintLayout.

3.1.3 Graphic editor

The layout is specified using an XML file. Android Studio offers a parallel graphical editor at. You can then easily switch from the XML file to the editor and vice versa.

To edit the layout, go to the layout XML, e.g.. Usually you first see the graphical editor:

Bottom left you can see two "tabs" with the identifiers design and text. There you can switch between the XML view (text) and the graphic view (design).

You definitely should be familiar with both views. Many things can be solved faster and more clearly in the text view. There you can also quickly copy components from other projects with a simple copy-n-paste.

For our first examples we will use two visible components particularly frequently: Button and TextView. TextView is a field in which text is displayed. He can Not edited by the user (that would be EditText).

You can find these and other components in the Design view Of your layout (e.g. activity_main.xml) in the subwindow palette:

In the design view, you can simply drag and drop the components to the left on the screen. Always look afterwards in the text view to see how exactly the component is configured.

3.2.1 Button and TextView

Button and TextView are first of all Java classes. It's worth taking a look official documentation (short API) of the Button and TextView classes. There you will find all XML properties (for layout) and all Java methods for programmatic access.

(It is interesting, for example, that Button is a subclass of TextView. Why? A button also contains text - the label - and has additional functionality, namely that it can be clicked. So the Button class simply "extends" the TextView class.)

Button in XML and Java

In the text view, a button looks like this, for example:

You should always delete the properties directly because they are absolute positioningin a world of different screen sizes not useful are. Just if you change the orientation (portrait to landscape), absolute position information regularly leads to screen salad.

With the property you can define the labeling of the button. The property is also extremely important. Use the ID to access in Java (e.g. in MainActivity.java) on the button to:

Also be Layout references between the components (in RelativeLayout and ConstraintLayout) via the ID.

If you change the ID, you should do so with the help of Refactoring do (right click Refactor> Rename ...) so that cross references in Java and in the layout are not destroyed.

You can do everything you define in the XML "programmatic" in Java check. For example, you can define or change the labeling:

You can also use the button deactivate, i.e. it remains visible, but can no longer be clicked (it is usually grayed out):

TextView in XML and Java

A TextView looks like this in the Text View, for example:

Interesting to see here is that sometimes no ID is present. But if you want to access this text, you need one. So add one yourself, making sure to put one in front of it:

Interesting properties are e.g. font size, style (bold, italic), color or alignment (left, right, centered). This is the best place for you in the design view in the right bar Attributes (you must first click on the corresponding component in the screen preview).

In the XML it looks like this and can of course also be edited here:

(The unit of measure "sp" is explained in the next section.)

Again, you can use the component in Java programmatically control:

3.2.2 Text input, switches, images

We'll introduce a few more components that might be of interest for your first apps.

EditText is a text field for the Input of text by the user. In the Design View there are numerous categories for this, such as "Plain Text" or "Multiline Text", but in the Text View you can see that it is always the EditText class with small differences in the properties.

API EditText →

CheckBox is a checkbox that is checked / checked or not. You define the initial state in the XML as follows:

In Java you have a corresponding method:

API CheckBox →

ToggleButton is similar to the CheckBox, but looks like a button with a marker that shows whether the button is in the ON or OFF state. Here, too, the property defines how the initial state is.

API ToggleButton →

ImageView shows an image file, e.g. in jpg or png format. You must first save the file in the resource directory of your project. Make sure that the file name does not contain any hyphens / minus signs and does not start with a number! If you then drag one onto the screen in Design View, you can select your image.

API ImageView →

We will deal with the subject of images in the modules Resources and Layout II.

3.2.3 Pixel density, dp and sp

With better and better resolutions, a problem has arisen for mobile application developers and for web developers, namely: How do I give the Size and spacing of my components? In the past, everything was measured in "pixels", i.e. in screen dots. A circle with a diameter of 100 pixels was roughly the same size or equally visible on all devices. With the new, extremely high resolutions, this circle was sometimes barely visible. The new devices were too high Pixel density, too many pixels in a small space, often measured in dpi (dots per inch).

The solution was to develop new units that were more or less comparable in size on all devices. In Android, this unit is called density-independent pixels or short dp. A "dp" should correspond to a pixel on a display of "medium" resolution, more precisely a display with 160 dpi. Note that this unit usually has a different name for other languages ​​and frameworks.

In short: Always use the unit dp for heights, widths and distances.

At Fonts use another unit again, namely the scale-independent pixels or short sp. This unit is basically the same as dp, but also adapts to the user-adjustable Base font size at. That is, when the basic font size is "normal", sp corresponds to the unit dp. If the user increases the basic font size, all sp-values ​​increase automatically (but of course not the dp-values). So a meaningful separation.

In short: Always use the unit sp for writing or texts.

(See also the article on Screen Densities.)

API: LinearLayout

LinearLayout packs all components in a horizontal or vertical row.

To try out LinearLayout, create a new project and go to the text view of.

Now replace ConstraintLayout with LinearLayout. It is best to delete with the BACKSPACE key, then the text will be replaced in both the opening and the closing tag. You replace

by

I.e. you do not need a "path" for LinearLayout.

Now add the "orientation" property with the value "vertical".

You can also delete all information that contains "tools". Make sure that the angle brackets are retained:

3.3.1 Layout with nesting

In principle, you layout with LinearLayout by adding several LinearLayout objects nest. Here is a simple example with two layout objects:

You can create amazingly complex layouts using nesting. Here's an example:

If you look at any window, whether on your mobile phone or on your laptop, you can draw a number of LinearLayout containers for most windows and usually recreate the window in Android as well.

3.3.2 Step-by-step example

How do you get a nested layout in Android Studio go? Let's assume you have already replaced your ConstraintLayout with a LinearLayout, i.e. your layout file looks like this:

Now you can in the Design view add additional layout containers. This is best done in the Component Tree-Window at the bottom left of the preview:

Select the Palette window the "Layout" tab and drag a linear layout (horizontal) twice into the Component Tree into the existing linear layout. It should look like this:

So that we can see something in the preview, we have to drag visible components into the design. Here, too, we work in Component Tree. Select in the palette the tab "Widgets" and drag three buttons into the upper horizontal LinearLayout and then two buttons into the lower horizontal LinearLayout.

You only see the top row of buttons! Why? The upper LinearLayout has the basic setting, i.e. the container tries to take up the entire screen and displaces the lower LinearLayout.

The solution is to set both (horizontal) linear layouts to:

You can see that while many layouts are possible, you may spend a lot of time finding the right fine adjustments. That only helps - as always - a lot of practice!

3.3.3 Setting options

orientation

What does it all mean? The orientation determines whether the contained elements are arranged horizontally or vertically.

So that's how...

... or so:

Layout width and height

At layout_width and layout_height there are two options:

  • match_parent: it is expanded "as far as possible", i.e. to the limit of the surrounding component (parent)
  • wrap_content: it is expanded "as far as necessary", i.e. as far as the content (text, image) requires

Replace the TextView with two buttons:

You can see that "match_parent" is set for the first button and "wrap_content" for the second button:

Alignment

About the property gravity you can set the alignment of the included components:

You will see accordingly:

You can go with gravity Align all components top, bottom, left, right or just centered.

weighting

With the widgets you can use the weighting of the components above layout_weight to adjust. These values ​​are relative to each other. In this example, the first button has weight 2, the second weight 1, i.e. the first has 2 of a total of 3 parts of space (i.e. 2/3 of the space), the second only 1/3.

Two other hugely important properties of visible components are Margin and Padding.

Margin and Padding

The Margin determines the Outside clearance, i.e. the distance from the edge of the component to the edge of the surrounding container:

You can also specify this for certain pages:

The Padding ("Filling") determines the Padding, i.e. the distance from the edge of the component to the content (text, image). Here for the button below:

text

Of course, you can also set the text for widgets such as buttons or text fields. Here you can simply enter the property in XML text to change:

API: RelativeLayout

The LinearLayout is about how the contained components are arranged within the container. A complex layout can be achieved by nesting.

With RelativeLayout one tries to go through the contained components Relationships (Eng. relations) to be specified to the extent that Android can position them sensibly. Since such relationships restrict the possible position of a component (to constrain), such a relationship can also be used Constraint call.

In a RelativeLayout-Object you can on the one hand two contained components A. and B. related to each other, e.g.

  • A and B should be aligned with each other at the top or
  • B should be to the right of A.

On the other hand, you can have an included component A. to the RelativeLayout object R. relate itself (i.e. the container of A), e.g.

  • A should be on the left edge of R or
  • A should be in the center of R.

To define the relationships / constraints, the respective ID a component (button, TextView etc.) is important. You can find this in the XML in the form "@ + id /". If you don't see one, you'll need to add this property yourself.

In the following we look at the possible relationships with examples. A table with all constraints can be found at Tutorialspoint.

3.4.1 Create RelativeLayout

If you have a fresh project with a ConstraintLayout, you have to change the layout file so that you see:

You may of course only apply the following relationships to components that are within these brackets.

Of course, you can also nest RelativeLayout and LinearLayout inside each other. The relationships have to be in a RelativeLayout container.

3.4.2 Relationships between included components

We will first deal with the relationships between two contained components A and B. These components can be any view, e.g. buttons, images or text fields.

One can go to Alignment define the following constraints for the edges. The actual properties are e.g. android: layout_alignTop. Here's an example:

For the sake of clarity, the following graphics are only Short forms to see the property identifier. Instead of "alignStart" it is actually called "android: layout_alignStart".

So you can align / align two components using an edge:

One can specify on which side there is a neighboring component. You can then use the distance Margin put.

example

Let's look at an example with three text components.

If you have a component without relationships these become easy top left positioned in the respective layout object.

Now you can easily move the component using the margin:

Now let's add two more Add text fields.

These should among themselves (below) and left-justified (alignStart) must be positioned. So we define the two texts relative to the first or the second:

Note the importance of the IDs in the code to be able to define the relationships.

3.4.3 Relationships with the parent component

For a component K, the parent component is the component "above it", that is, the container that contains K In this case, this is our RelativeLayout object R.

We can K to the edge of the parent component R:

We can also within R center:

example

For example, if you want to put a button at the bottom of the screen ...

... one would write

So the steps to achieve the above layout are:

  1. put the button at the bottom (alignParentBottom)
  2. center it in the horizontal (centerHorizontal)
  3. set a fixed distance to the lower edge (marginBottom)

Of course, you can also use a LinearLayout within a RelativeLayout and vice versa.

(A) LinearLayout

Realize the following layout and also note the Hints below. Use the following components (sometimes several times):

  • LinearLayout
  • Button
  • Text field (TextView)
  • Image field (ImageView)

In the landscape orientation it should look like this:

Hints

  • You must use multiple LinearLayout objects (nested)
  • Set the width (layout_width) of the text field and image field to a fixed value, e.g. "100dp"
  • If you don't see components, consider the height where "match_parent" and where "wrap_content" should be
  • Drag to position the buttons gravity into consideration (see section "Alignment")

(B) RelativeLayout

Use RelativeLayout, a text field and two buttons to achieve the following layout:

In the landscape orientation it should look like this:

Prof. Dr. Michael Kipp
Augsburg University of Applied Sciences
At the university 1
86161 Augsburg
Room J3.18
Tel: +49 821 5586 3509