Google+

Android4Beginners.com

Apps development for Android step by step

Lesson 2.1: How to build Android app with simple, but powerful LinearLayout? Plus layout orientation as well as size and weight of elements

If you created app based on previous lessons, you had already contact with layout tag, though we haven’t analyzed how it works. Default layout for new app in Android Studio is RelativeLayout, but we will start with another layout type – called LinearLayout. It is easy to use and still very helpful in many situation.

LinearLayout arranges all layout elements next to each other – element by element. They could be set horizontally (into columns) or vertically (into rows).

It is easier to understand when you look at the illustration. Let’s imagine that our layout includes 3 elements. By the way those element could be TextViews, but also images, buttons, lists, other layouts etc.

LinearLayout could arrange element horizontally from left to right or vertically from top to bottom (Android Studio).

LinearLayout could arrange element horizontally from left to right or vertically from top to bottom (Android Studio).

Step 1. Use LinearLayout with many TextView elements.

Now it’s time to build such a layout. Let’s start from the beginning. Open activity_main.xml file from layout folder (you could learn about it in Lesson  0). Every layout file has main layout XML tag (so called root). The root has to have namespace declaration (xmlns:android and xmlns:tools).

If you haven’t modified yet the layout of the first app the code should start with <RelativeLayout some_attributes> and finish with </RelativeLayout>. There should be one <TextView some_attributes> element inside too.

First, change tag name RelativeLayout to LinearLayout both at the beginning and at the end of the code. We could also delete all padding attributes so the code would be shorter (we would learn about paddings soon), but it’s not necessary. Moreover we have changed android:id value of TextView to “text1”, but it’s also optional (ID names depends on your preferences, as we would use a few TextViews it would be easier to follow them, as we give them numbers).

This is a code example of activity_main.xml file after above changes:

Remember that order of tag attributes doesn’t matter.  You could learn more about XML syntax as well as xmlns:android and xmlns:tools attributes from Appendix A: Android XML syntax. In this lesson we would focus only on attributes related to layout presentation. You could learn more about TextView from the previous lesson.

Look at the preview in Android Studio – nothing changed. Both RelativeLayout and LinearLayout with one TextView looks the same. Now add two more TextViews – you could copy whole elements. You have to use different IDs for every layout element, but value attribute android:text could stay the same (or you could change it to another string from strings.xml).

Now you should see three text strings next to each other. Add different background color to each TextView – it would be easier to see where elements start and finish (read here how to add background color).

This is code of second TextView with green background:

Now we have three independent TextView elements in LinearLayout. They could have different settings, like background color, font style & size, dimensions etc. (Android Studio)

Now we have three independent TextView elements in LinearLayout. They could have different settings, like background color, font style & size, dimensions etc. (Android Studio)

Step 2. Change LinearLayout from horizontal to vertical orientation.

Default setting for LinearLayout is horizontal orientation, so elements are positioned in a row from left to right, but we could change it and position next element below previous one (like in a column).

Attribute android:orientation has two values: horizontal (default so we don’t have to add it) and vertical. Let’s change to vertical and leave all other elements as they are now.

The same three TextView elements as in the previous step, but now arranged vertically (Android Studio)

The same three TextView elements as in the previous step, but now arranged vertically (Android Studio)

Mind that this isn’t screen orientation, but only layout orientation. If we rotate the screen from portrait to landscape, layout arrangement would stay the same.

The same LinearLayout code, but on landscape screen (Android Studio).

The same LinearLayout code, but on landscape screen (Android Studio).

Step 3. Define the size of layout elements: layout_width and layout_height.

Every layout and layout element must contain attributes layout_width and layout_height that defines its size. The size could have specific value or be relative.

Specific values are set preferably in dp (read about measurement units in Android).

We have three TextViews. Let’s set their width to 100dp, 200dp, 300dp and height to 20dp, 40dp, 60dp respectively.

This is a sample code of the third TextView, but they all look similar:

And this is layout preview.

Now every TextView has different size set by us in density-independent pixels so it would be identical on every device (Android Studio)

Now every TextView has different size set by us in density-independent pixels so it would be identical on every device (Android Studio)

But there is one important remark. Android doesn’t care whether layout elements fit to screen. If they are too big, they would be presented out of screen.

Return to horizontal orientation of the layout (set android:orientation to horizontal or delete that attribute so it choose default value). Now you see that the part of TextView three is out of screen. This is because the screen width of that device is 480dp and all three TextViews together have 600dp. Of course on some bigger devices that could be visible, but you have to be very careful with using specific values in layout.

If you declare too long width or height some layout element would be out of screen (Android Studio)

If you declare too long width or height some layout element would be out of screen (Android Studio)

There is also a problem if width or height is too short for a content.

Declaring smaller element size than content would make part of the content invisible (Android Studio)

Declaring smaller element size than content would make part of the content invisible (Android Studio)

Step 4. Use relative width or height for layout elements (wrap_content and match_parent)

The default value for layout_width and layout_height of TextViews in our layout was “wrap_content”. This is very useful option. It makes Android too calculate on its own how much space is needed for specific content. Moreover this is done dynamically. So if the content becomes shorter or longer during app activity, element holding that content would become smaller or bigger respectively. And if the content is longer than screen width then “new line “ would be added (element would be higher). Of course there is also possibility of going out of dedicated space (or screen), but only if content is bigger that total available space.

Let’s do an experiment. We have three TextViews with identical content. Set they width and height back to wrap_content and then change text size. As we see element with larger text size become automatically bigger.

We could change only one of those attributes to wrap_content. It means that one dimension stays fixed and the second try to take as much space as possible to wrap whole content.

The second and third TextViews have the same text size, but the third additionally has fixed width. So Android takes as much height as is needed to show content (Android Studio)

The second and third TextViews have the same text size, but the third additionally has fixed width. So Android takes as much height as is needed to show content (Android Studio)

Another useful value is match_parent. That allocates as much space as is used by parent layout element (so element in which we contain other elements). In our example parent layout element is LinearLayout and all three TextViews are its children.

How big is parent element? We don’t know and… we don’t care. If parent becomes larger all children with match_parent become larger too (and opposite). So if we rotate a device to landscape, first TextView would be even longer as it still matches parent width.

Let’s change width of first TextView to match_parent. Now we see that it becomes as long as screen.

 Match_parent makes element as long or as high as its container called parent (Android Studio)

Match_parent makes element as long or as high as its container called parent (Android Studio)

Now you could do small experiment. Set also height too match_parent. Now first TextView takes all the screen, thus second and third ones go out of screen.

Mind that in the past match_parent was called fill_parent, but now the second name is deprecated.

Maybe you noticed also that LinearLayout root element also has width and height set to match_parent. That means that it fills whole screen (there is some hidden view that represents current screen size).  In most of cases is has to stay that way.

Step 5. Use all available space for layout elements: layout_weight.

In our small experiment in the previous step whole screen was taken by the first TextView. But how to use all available space left – so the space not used by other elements. There is another wonderful layout attribute called layout_weight. It allows layout elements to utilize free space.

Let’s go back too layout when we had three TextViews one under another (layout orientation set to vertical). Most of the screen is empty. We could try to calculate the height needed to fill the screen, but it would work only on specific devices. If we add fixed height it could be too long or too short for other devices. Fortunately all we have to do is to use layout_weight.

As the value of that attribute we use an integer number, for instance 1, 2 or 5. Let’s start with 1. We should also change layout_height to 0dp to inform Android that we would use weight instead.

This is a sample code and preview.

Attribute layout_weight informs layout element that it could use a free space (Android Studio)

Attribute layout_weight informs layout element that it could use a free space (Android Studio)

If we now change it to 2, 5 or 10 nothing would happen as only one element competes for free space. But situation would be different when we add android_weight to more elements. The rule is quite simple, but it takes some problem to novices.

Android adds weights from all elements. Then reserve minimum space needed for the content. The rest (so free space) is divided among elements with weights based on following equation: element_weight/total_weight.

If there are two elements with weight 1, both would take 1/2 so 50% of free space each. If the first has weight 2 and the second weight 3, first would take 2/5 so 40%, and second – 3/5 so 60%. If there are three elements with weights 1, 2 and 3, first would use 1/6 (about 16.6%), second 2/6 = 1/3 (about 33.3%) and third 3/6 = 1/2 (50%) of free space.

Adjusting the value of weight you could divide free space among layout element (Android Studio)

Adjusting the value of weight you could divide free space among layout element (Android Studio)

Mind that two elements having the same weight could have different size. Weight only adds part of free space to their current sizes. So if one element had original width 30dp (and weight 1), another 50dp (and weight 1) and free space was 80dp, first would have 70dp and second 90dp.

You could use weight both for width and height, but if there is only one element in a row or in a column, it would fill all space and thus it would work as match_parent.

Summary: To arrange elements on Android app screen we use layouts. The basic layout type is called LinearLayout. It arranges elements horizontally or vertically. You could declare size of elements giving specific values in dp or using relative values match_parent and wrap_content. Attribute layout_weight allows you to dynamically divide free space left among content elements.

Previous:
Next: