Layouts

OBJECTIVES

  1. What are Layouts
  2. Exercise : Simple Calculator App
  3. Pellentesque accumsan auctor tortor.

1. What are Layouts ?

Layouts are like canvas which is use to place widgets (UI components) with the child relationship to corresponding Views. When we create android app we need to design views and we know from last chapter (Views) all the widgets are directly or indirectly derived from View. Always remember when a widget is derived directly or indirectly form ViewGroup (ViewGroup → View) that widget has a capability to add widget(UI component) as child element and Layouts are experts in this. Layout is used to place widgets in a proper structure based on the definition or capabilities of Layout. There are five common layouts available in android and from my point of view it increase with new releases of Android versions. You can also create your custom layout by using any of the base Layout class. Let’s look for the inheritance tree of Layout, try to analysis below fig.

As you can see from  above figure except TableRow and TableLayout all the Layouts are directly derived from ViewGroup. So let’s try to have some hands on experience with demo example on these layout.

1.1 Declaring Layouts

You can declare layout in two ways :

  1. Using XML layout : this is very easy and convenient of declaring layout as all the UI component classes are easily accessible in XML format. Just like designing a HTML page where you just need to deal with markup tags, in android all the UI can be accessible using there XML element format.
  2. Using Java code : this is little hard way of accessing UI components , but very useful in generating dynamic content. You can create and design a complete layout using this technique but it is very hard to place widgets in exact position and place you need.

1.1 Writing XML layout

Writing XML layout is very easy , you can write it down by using text editor or use android studio to design it by drag and drop. Most programmer use both way to accomplish this but for beginner i prefer to go with android studio design. When you design your layout it always come with the root or parent element. So it may by any kind of root layout element like LinearLayout or ConstraintLayout or any one of the layout, and inside a parent layout  you can structured views. As shown in below figure using LinearLayout with vertical orientation, center gravity, layout_margin 15dp.

In below figure we are defining Linear Layout with vertical orientation (1) and gravity to center (2) with total layout margin (15dp). Since this layout is with vertical orientation which means one component per row it will place each widget i.e. EditText (4 and 5) and Button (6) in n- row x 1 col format. This is a very easy way of writing XML layout or designing using Android Studio design. Now lets, go through each of this layout one by one.

 

1.2 LinearLayout

LinearLayout is a single directional layout and used to place elements either vertically (ie. n rows x 1 col) format or horizontally (ie. 1 row x n cols) format. Very easy to use layout and i love it. The vertical or horizontal direction is laid out with android:orientation attribute with value “vertical” or “horizontal”

The direction of LinearLayout is dependent on the screen size of the device and android devices comes is different resolution see the chart below.

Size, Resolution and Density of different devices

Name

Play Store

Size

Resolution

Density

Pixel XL

5.5"

1440x2560

560dpi

Pixel 2 XL

5.99"

1440x2880

560dpi

Pixel 2

5.0"

1080x1920

420dpi

Pixel

5.0"

1080x1920

xxhdpi

Nexus S

4.0"

480x800

hdpi

Nexus S

4.0"

480x800

hdpi

Nexus 6P

5.7"

1440x2560

560dpi

Nexus 6

5.96"

1440x2560

560dpi

Nexus 5X

5.2"

1080x1920

420dpi

Nexus 5

4.95"

1080x1920

xxhdpi

Nexus 4

4.7"

768x1280

xhdpi

Galaxy Nexus

4.65"

720x1280

xhdpi

5.4" FWVGA

5.4"

480x854

mdpi

5.1" WVGA

5.1"

480x800

mdpi

4.7" WXGA

4.7"

720x1280

xhdpi

4.65" 720p (Galaxy Nexus)

4.65"

720x1280

xhdpi

4" WVGA (Nexus S)

4.0"

480x800

hdpi

3.7" WVGA (Nexus One)

3.4"

480x800

hdpi

3.7" FWVGA slider

3.7"

480x854

hdpi

3.4" WQVGA

3.4"

240x432

ldpi

3.3" WQVGA

3.3"

240x400

ldpi

3.2" QVGA (ADP2)

3.2"

320x480

mdpi

3.2" HVGA slider (ADP1)

3.2"

320x480

mdpi

2.7" QVGA slider

2.7"

240x320

ldpi

2.7" QVGA

2.7"

240x320

ldpi

Pixel C

9.94"

2560x1800

xhdpi

Nexus 9

8.86"

2048x1536

xhdpi

Nexus 7 (2012)

7.0"

800x1280

tvdpi

Nexus 7

7.02"

1200x1920

xhdpi

Nexus 10

10.05"

2560x1600

xhdpi

7" WSVGA (Tablet)

7.0"

600x1024

mdpi

10.1" WXGA (Tablet)

10.1"

800x1280

mdpi

  So, whenever we create design we need to test this performance and compatibility with different devices. Let’s do an exercise where you want to display bunch of Button in vertical format using LinerLayout.

Exercise : LayoutDemo (linearlayout)

Github Link : https://github.com/androidacademia/BLayoutDemo 

  1. Create an project and name it LayoutDemo.
  2. Add a new layout name linear_demo.xml from resources and select root element as LinearLayout.

  1. Now change the orientation of layout to vertical

  1. Now drop bunch of Button on layout , since we are using vertical orientation you will see buttons in row by row format.
  2. I am using here 22 buttons but only 10 are completely visible if you use Nexus 4, remaining will completely out of the device height, you can test your layout on different device after designing it.

  1. To test layout on various devices just just click on Device in Editor icon  and from drop down select different device. Let’s say I am selecting Nexus One, here only 9 button are completely visible and remaining move out of the box height.

  1. Now try to change the orientation of layout from portrait to landscape, select it from Orientation in Editor(O)  only 5 buttons are visible

This is only issue with linear layouts.

  1. Solution to this problem
  1. Solution is ScrollView. Drag and drop a ScrollView and just place all your Button widget inside ScrollView see fig below

  1. Run you app after setting setContentView(R.layout.linear_demo) you will have smooth scroll format for your Buttons.
  2. This is not the only one solution instead there are many more we will talk about it on “Supporting different Screen Size”.

1.2 TableLayout

TableLayout is derived from LinearLayout which arrange child elements into row and column format. In table layout TableRow element define the rows and columns are defined by the child elements of TableRow. So if you want to create a table of  3x3 with each row contains 3 columns with Button the structure will look like below

1.3 ConstraintLayout

ConstraintLayout is more flexible way of designing Layout as all the sibling views has relationship with parent layout. It is a flat view hierarchy, very much alike relative layout but more flexible and easier to use with Android Studio Layout Editor. You can also convert any layout to constraintlayout by simply making right click to layout inside component editor and selecting “convert <layout> to ConstraintLayout”

Simple layout example given below:

With ConstraintLayout we define constraint between siblings or with parent. Look for above fig and ConstraintLayout code, TextView define constraint with parent(i.e. ConstraintLayout) with app:layout_constraintBottom_toBottomOf=”parent”, app:layout_constraintLeft_toLeftOf = “parent”, app:constraintRight_toRightOf = “parent” and app:layout_constraintTop_toTopOf = “parent”. We can add and remove this constraint lets try it.

From the above figure it can be done easily just select the point available on sibling view and add the constraint by moving mouse to the end of sibling point or parent layout.

We can remove constraint simply by selecting arrow and pressing delete button from keyboard.

****** Manually adding a constraint might sometime difficult to handle, I suggest everybody to make a design and then click on the magic band   so that studio automatically apply the constraint.

2. Exercise: Simple Calculator Layout

Let's have an exercise on Calculator app, a simple calculator app layout design using ConstraintLayout and TableLayout with Button and TextView.

Github code :

  1. Create an app with name CalculatorDesign
  2. Leave everything default
  3. Open acitivity_main.xml and drop a TableLayout.
  4. By default with TableLayout you will get 4 TableRow
  5. Add one more
  6. Make TableLayout layout_width and layout_height to “wrap_content”
  7. At each row add four buttons with layout_width and layout_height of 80dp
  8. Now add a TextView at the top middle of ConstraintLayout and make layout_width to “match_parent” and layout_height to “wrap_content”
  9. Set textSize attribute value to 36sp (always use sp with TextView or displaying text value)
  10. Set TextView textAlignment to vieEnd , gravity to “center|bottm”.
  11. Your xml code and layout will look like below.

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

   xmlns:app="http://schemas.android.com/apk/res-auto"

   xmlns:tools="http://schemas.android.com/tools"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   tools:context=".MainActivity">

   <TableLayout

       android:id="@+id/tableLayout2"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginStart="32dp"

       app:layout_constraintBottom_toBottomOf="parent"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toBottomOf="@+id/textView"

       app:layout_constraintVertical_bias="1.0">

       <TableRow

           android:layout_width="match_parent"

           android:layout_height="match_parent">

           <Button

               android:id="@+id/button"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="AC" />

           <Button

               android:id="@+id/button2"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="+/-" />

           <Button

               android:id="@+id/button3"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="%" />

           <Button

               android:id="@+id/button4"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="/" />

       </TableRow>

       <TableRow

           android:layout_width="match_parent"

           android:layout_height="match_parent">

           <Button

               android:id="@+id/button5"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="7" />

           <Button

               android:id="@+id/button6"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="8" />

           <Button

               android:id="@+id/button7"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="9" />

           <Button

               android:id="@+id/button8"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="X" />

       </TableRow>

       <TableRow

           android:layout_width="match_parent"

           android:layout_height="match_parent">

           <Button

               android:id="@+id/button9"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="4" />

           <Button

               android:id="@+id/button10"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="5" />

           <Button

               android:id="@+id/button11"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="6" />

           <Button

               android:id="@+id/button12"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="-" />

       </TableRow>

       <TableRow

           android:layout_width="match_parent"

           android:layout_height="match_parent">

           <Button

               android:id="@+id/button13"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="1" />

           <Button

               android:id="@+id/button14"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="2" />

           <Button

               android:id="@+id/button15"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="3" />

           <Button

               android:id="@+id/button16"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="+" />

       </TableRow>

       <TableRow

           android:layout_width="match_parent"

           android:layout_height="match_parent">

           <Button

               android:id="@+id/button17"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="0" />

           <Button

               android:id="@+id/button18"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="." />

           <Button

               android:id="@+id/button20"

               android:layout_width="80dp"

               android:layout_height="80dp"

               android:text="=" />

       </TableRow>

   </TableLayout>

   <TextView

       android:id="@+id/textView"

       android:layout_width="0dp"

       android:layout_height="0dp"

       android:layout_marginBottom="8dp"

       android:layout_marginEnd="8dp"

       android:layout_marginStart="8dp"

       android:layout_marginTop="8dp"

       android:gravity="center|bottom"

       android:text="TextView"

       android:textAlignment="viewEnd"

       android:textSize="36sp"

       app:layout_constraintBottom_toTopOf="@+id/tableLayout2"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Try it out and try to create some more complex design…..

3. Layout Performance

Excessive use of View hierarchy may slow down your app performance hence it is very important to measure your app performance before launching it to playstore. In this topic we will learn whether our layout is slow  your app performance or not. We will use lint tool to analyze  your app performance.

Let’s take our last example on Calculator design application we will run lint tool to analyze our layout performance and try to correct it.

  1. Open your Calculator Design app
  2. Go to Analyze → Inspect Code

  1. Just click “OK” , here we are inspecting whole project look of the inspection results which might appear at bottom window. You will get following results

  1. We will look for Internationalization and Performance , as you can figure out from above figure there is 1 error and 20 warnings. Let’s try to open it

As you can see it tells up about the wrong textAligment with current api which i am using here is 22, now you have two opportunity either you can suppress it or don’t use android:textAligment. You can suppress it by adding suppress annotation by clicking Suppress and add the Suppress annotation.

        

I will go with second option , i will remove this attribute.

  1. Open activity_main.xml from TextView remove android:textAlignment = “viewEnd” and run inspect code again.

As you can see there is no error. As you can see it’s very easy to work with Lint tools. Now let’s test the Performance of layout

  1. Open AndroidLint:Performance (it is showing 19 warning) here you will find it’s telling about unused imports, this these are unused ids in your application if you use any one this id , the waring will be reduced to 18 . let’s try I am going to use R.id.button by creating an object of Button in my MainAcvity.java

private Button btn;

btn = findViewById(R.id.button);

  1. Run inspect code again

Now you can see the warning is reduced to 18, in a similar way you can reduce other.

We will talk about Lint and performance in other chapter. But for now it is ok by testing the layout performance using Lint.