Android offers a collection of view classes that act as containers for views. These container classes are called layouts (or layout managers), and each implements a specific strategy to manage the size and position of its children.LinearLayout Organizes its children either horizontally or vertically
TableLayout Organizes its children in tabular form
RelativeLayout Organizes its children relative to one another or to the parent
FrameLayout Allows you to dynamically change the control(s) in the layout
GridLayout Organizes its children in a grid arrangement

LinearLayout

Vertical, default weight and gravity value

linearlayout_defaultweight_gravity

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="one"/>
    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="two"/>
    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="three"/>
</LinearLayout>

Linear with weight configurations

layout_weight of the center EditText is bigger than all

linearlayout_weightconfigurations

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <EditText android:layout_width="fill_parent" android:layout_weight="0.0"
        android:layout_height="wrap_content" android:text="one"
        android:gravity="left"/>
    <EditText android:layout_width="fill_parent" android:layout_weight="1.0"
        android:layout_height="wrap_content" android:text="two"
        android:gravity="center"/>
    <EditText android:layout_width="fill_parent" android:layout_weight="0.0"
        android:layout_height="wrap_content" android:text="three"
        android:gravity="right"
        />
</LinearLayout>

android:gravity vs. android:layout_gravity

android:gravity: set for text

android:layout_gravity: set for position of item

gravity_vs_gravitylayout

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <EditText android:layout_width="wrap_content" android:gravity="center"
        android:layout_height="wrap_content" android:text="one"
        android:layout_gravity="right"/>
</LinearLayout>

TableLayout

The TableLayout layout manager is an extension of LinearLayout. This layout manager structures its child controls into rows and columns.

table_layout

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <TableRow>
        <TextView android:text="First Name:"
            android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <EditText android:text="Edgar"
            android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </TableRow>
    <TableRow>
        <TextView android:text="Last Name:"
            android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <EditText android:text="Poe"
            android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </TableRow>
</TableLayout>

RelativeLayout

This layout manager implements a policy where the controls in the container are laid out relative to either the container or another control in the container.

relative_layout

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TextView android:id="@+id/userNameLbl"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:text="Username: "
        android:layout_alignParentTop="true" />
    <EditText android:id="@+id/userNameText"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:layout_toRightOf="@id/userNameLbl" />
    <TextView android:id="@+id/pwdLbl"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_below="@id/userNameText"
        android:text="Password: " />
    <EditText android:id="@+id/pwdText"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:layout_toRightOf="@id/pwdLbl"
        android:layout_below="@id/userNameText" />
    <TextView android:id="@+id/pwdCriteria"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:layout_below="@id/pwdText"
        android:text="Password Criteria... " />
    <TextView android:id="@+id/disclaimerLbl"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="Use at your own risk... " />
</RelativeLayout>

FrameLayout

Dynamically display a single view, but you can populate it with many items, setting one to visible while the others are invisible.

framelayout

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frmLayout"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ImageView
        android:id="@+id/oneImgView" android:src="@drawable/one"
        android:scaleType="fitCenter"
        android:layout_width="fill_parent" android:layout_height="fill_parent"/>
    <ImageView
        android:id="@+id/twoImgView" android:src="@drawable/two"
        android:scaleType="fitCenter"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:visibility="gone" />
</FrameLayout>

MainActivity.java

package com.trankyphat.app.layoutmanager;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private ImageView one = null;
    private ImageView two = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        one = (ImageView)findViewById(R.id.oneImgView);
        two = (ImageView)findViewById(R.id.twoImgView);

        //Hide one when click two and hide two when click one
        one.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view) {

                //Display Two
                two.setVisibility(View.VISIBLE);
                //Hide clicked image
                view.setVisibility(View.GONE);
            }});
        two.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view) {
                one.setVisibility(View.VISIBLE);
                view.setVisibility(View.GONE);
            }});
    }
}

You generally use FrameLayout when you need to dynamically set the content of a view to a single control. Although this is the general practice, the control will accept many children, as we demonstrated.

Another interesting aspect of the FrameLayout is that if you add more than one control to the layout, the size of the layout is computed as the size of the largest item in the container. In code example, the top image is actually much smaller than the image behind it, but because the size of the layout is computed based on the largest control, the image on top is stretched.

Note: Also note that if you put many controls inside a FrameLayout with one or more of them invisible to start, you might want to consider using setMeasureAllChildren(true) on your FrameLayout. Because the largest child dictates the layout size, you’ll have a problem if the largest child is invisible to begin with: when it becomes visible, it is only partially visible. To ensure that all items are rendered properly, call setMeasureAllChildren() and pass it a value of true. The equivalent XML attribute for FrameLayout is android:measureAllChildren=”true”.

GridLayout

It lays out views in a grid pattern of rows and columns, somewhat like TableLayout. However, it’s easier to use than TableLayout. With a GridLayout, you can specify a row and column
value for a view, and that’s where it goes in the grid. This means you don’t need to specify a view for every cell, just those that you want to hold a view. Views can span multiple grid
cells. You can even put more than one view into the same grid cell.

gridlayout

When laying out views, you must not use the weight attribute, because it does not work in child views of a GridLayout. You can use the layout_gravity attribute instead. Other interesting attributes you can use with GridLayout child views include layout_column and layout_columnSpan to specify the left-most column and the number of columns the view takes up, respectively. Similarly, there are layout_row and layout_rowSpan attributes. Interestingly, you do not need to specify layout_height and layout_width for GridLayout child views; they default to WRAP_CONTENT

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/gridLayout"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK"
        android:id="@+id/button3"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/gridLayout"
        android:layout_toEndOf="@+id/gridLayout"
        android:layout_row="2"
        android:layout_column="3" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button4"
        android:layout_row="3"
        android:layout_column="3"
        android:layout_columnSpan="3" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button2"
        android:layout_row="2"
        android:layout_column="4"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:layout_row="2"
        android:layout_column="5" />

</GridLayout>

Customizing the Layout for Various Device Configurations

When building a layout, Android will find and load layouts from specific folders based on the configuration of the device. A device can be in one of three configurations: portrait, landscape, or square (square is rare). To provide different layouts for the various configurations, you have to create specific folders for each configuration from which Android will load the appropriate layout. As you know, the default layout folder is located at res/layout. To support portrait display, create a folder called res/layout-port.

For landscape, create a folder called res/layout-land. And for a square, create one called res/layout-square. A good question at this point is, “With these three folders, do I need the default layout folder (res/layout)?” Generally, yes. Android’s resource-resolution logic looks in the configuration specific directory first. If Android doesn’t find a resource there, it goes to the default layout directory. Therefore, you should place default layout definitions in res/layout and the customized versions in the configuration-specific folders.

Another trick is to use the <include /> tag in a layout file. This allows you to create common chunks of layout code (for example, in the default layout directory) and include them in layouts defined in layout-port and layout-land. An include tag might look like this:

<include layout="@layout/common_chunk1" />

If the concept of include interests you, you should also check out the <merge /> tag and the ViewStub class in the Android API. These give you even more flexibility when organizing layouts, without duplicating views.

Note that the Android SDK does not offer any APIs for you to programmatically specify which configuration to load—the system simply selects the folder based on the configuration
of the device. You can, however, set the orientation of the device in code, for example, using the following:

import android.content.pm.ActivityInfo;
...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

This forces your application to appear on the device in landscape mode. Go ahead and try it in one of your earlier projects. Add the code to your onCreate() method of an activity, run it in the emulator, and see your application sideways.

Android 6 – Layout Managers

Category: Uncategorized
0
4508 views

Join the discussion

Your email address will not be published. Required fields are marked *