Sunday, March 13, 2016

Lesson 6. Layout types. Key differences and properties

LinearLayout - displays View-elements as a single row (if it is Horizontal) or a single column (if it is Vertical). I used it in the previous lesson, when demonstrating usage of layout-files during screen orientation change.
TableLayout - displays elements in the form of a table, with rows and columns.
RelativeLayout - each element’s position is configured relatively to other elements.
AbsoluteLayout - each element is specified an absolute position on the screen in the coordinate system (x, y)
Lets observe these types
  1. ANDROID TRAINING IN KATHMANDU
  2. ANDROID TRAINING IN LALITPUR 
  3. APP DEVELOPMENT IN KATHMANDU

LinearLayout (LL)

This type of a ViewGroup is set as default when creating new layout-files. It is really convenient and flexible enough to create screens of different complexity. LL has an Orientation property, which defines how will the child elements be positioned - in a vertical or horizontal line.
Let’s make a simple and clear example.
Create a project:
Project name: P0061_Layouts
Build Target: Android 2.3.3
Application name: Layouts
Package name: ru.startandroid.develop.layouts
Create Activity: MainActivity

Open main.xml layout-file and place the following code inside:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:orientation="vertical">
</LinearLayout>
Now we have a LinearLayout with vertical orientation as a root element.
Drag three buttons from the left to the root LinearLayout. They are positioned horizontally.

Now change Orientation property to horizontal for LL in Properties and save (CTRL+SHIFT+S) - buttons are positioned horizontally

A ViewGroup can be inserted into another ViewGroup. Let’s place two other LL into one. Delete all the elements from main.xml (three buttons) except of the root LL. Specify vertical orientation for the root LL and add two new horizontal LL inside it. They are located in the Layouts section in the list of elements on the left. Let me remind you, that you can drag and drop elements from the list not only to the screen, but also to the specific element in the Outline tab.
Add three buttons inside each horizontal LL. Now we have got two horizontals rows of buttons.

TableLayout (TL)

TableLayout consists of rows TableRow (TR). And each TR contains View elements that form columns. So the number of Views in TR is a number of columns. But the number of columns in  a table must be equal for all rows. That’s why, when different TRs have different numbers of View-elements (columns), the overall number of columns is defined by the TR with the maximum number. Let’s observe an example.
Create layout-file tlayout.xml with TableLayout as a root element.

Add three TableRow rows into the root TableLayout (from Layouts section on the left) and add two buttons into each row. The result: our table has got three rows and two columns.

Add a few more buttons to the first row. The number of columns now equals 4, as it is defined by the row with the maximum number of elements and it is the first row in our case. For the second and the third rows the third and the fourth columns are empty.

Add a TextView and a Button to the second row and make text in the added TextView empty. Do the same with the third row. We can see that these elements are now placed in the third and the fourth column. And because TextView is empty and not seen on the screen, it seems like the third column in the second and third rows is empty.

The width of the column is defined by the widest element in this column. Enter some text into one of the TextViews and we can see that it has made a column wider.

Now I will remove elements of the fourth column and build a screen like this. Try to do it on your own as an exercise.

TL can contain not only TRs, but also simple Views. For example, add Button just into the TL, not into TR and you will see how it stretches to the width of the whole table.

RelativeLayout (RL)


In this type of Layout, each View-element can be positioned in a specific way relatively to the specified View-element.
Types of relationships:
1) to the left, right, above or below the specified element (layout_toLeftOf, layout_toRightOf, layout_above, layout_below)
2) aligned by the left, right, top or bottom edge of the specified element (layout_alignLeft, layout_alignRight, layout_alignTop, layout_alignBottom)
3) aligned by the left, right, top or bottom edge of a parent (layout_alignParentLeft, layout_alignParentRight, layout_alignParentTop, layout_alignParentBottom)
4) centered vertically, centered horizontally, centered vertically and horizontally relative to its parent (layout_centerVertical, layout_centerHorizontal, layout_centerInParent)
More details are available in help.

Create rlayout.xml and copy and paste this xml-code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Type here:">
</TextView>
<EditText
android:id="@+id/entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/label"
android:background="@android:drawable/editbox_background">
</EditText>
<Button
android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/entry"
android:layout_marginLeft="10dip"
android:text="OK">
</Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/ok"
android:layout_toLeftOf="@+id/ok"
android:text="Cancel">
</Button>
</RelativeLayout>
RelativeLayout is a the root element here.
We will get such a screen:

We are interested in xml-code. I will now shortly describe unknown attributes and their meanings:
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:id="@+id/entry"

- the android word in the name of each element is a namespace, I will omit it in the explanations. 
id - the element ID,
layout_width (the width of the element) and layout_height (the height of the element) can be specified in absolute values or can be the following: fill_parent (maximum available width or height in the bounds of its parent) and wrap_content (width of height is defined by the content of an element). Help states that there is also match_parent. It is the same as fill_parent. For some reasons, developers of the system decided that match_parent name is more convenient and they will stop using fill_parent soon. For now, it’s left for compatibility. So remember that match_parent = fill_parent and we will be trying to use match_parent further. Later we will stop on this and analyze it in more detail.

Now let’s get back to our elements. In the example we can see a TextView, EditText, and two Buttons - OK and Cancel. Let’s look through the attributes we are interested in.


TextView 
android:id="@+id/label" - ID
android:layout_width="match_parent" - occupies all the available width (even though, it’s not visible on the screen) 
android:layout_height="wrap_content" - height defined by the content 
it is not related to anything

EditText 
android:id="@+id/entry" - ID
android:layout_width="match_parent" - occupies all the available width
android:layout_height="wrap_content" - height defined by the content
android:layout_below="@id/label" - located below the TextView (reference by ID)

Button_OK 
android:id="@+id/ok" – ID
android:layout_width="wrap_content" - width defined by the content 
android:layout_height="wrap_content" – height defined by the content 
android:layout_below="@id/entry" - is located below EditText
android:layout_alignParentRight="true" - is aligned by the right edge of the parent
android:layout_marginLeft="10dip" – has a margin on the left (for Button_Cancel not to be adjacent)

Button_Cancel
android:layout_width="wrap_content" - width defined by the content 
android:layout_height="wrap_content" – height defined by the content 
android:layout_toLeftOf="@id/ok" - located to the left of Button_OK
android:layout_alignTop="@id/ok" - aligned by the top edge of Button_OK


You can add some more elements and experiment with their locations.
Pay your attention, that a View element can have no ID (android:id). For example, it is not usually needed for a TextView, because most of the times they are static and we rarely refer to them in the application. EditText is different - we work with the text field content, and a Button - we need to process clicks and to know exactly which Button has been pressed. In the future, we will see one more reason to specify an ID for a View-element

AbsoluteLayout (AL)

Provides absolute positioning of elements on the screen. You specify the coordinates for the left top corner of the component.
Create alayout.xml with AbsoluteLayout as a root element

Now try to add different elements by dragging them to the screen. They are not aligned as in LinearLayout or in TableLayout, but placed where you dragged them. So it is absolute positioning.

Open xml-code and note that for specifying coordinates layout_x and layout_y properties are used
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="42dp"
android:layout_y="62dp"
android:text="Button">
</Button>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="142dp"
android:layout_y="131dp"
android:text="TextView">
</TextView>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="55dp"
android:layout_y="212dp"
android:text="CheckBox">
</CheckBox>
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="171dp"
android:layout_y="318dp"
android:text="RadioButton">
</RadioButton>
</AbsoluteLayout>


First you might think that this is the most convenient and intuitive method of placing elements on the screen - they are placed wherever you want at once. But this is only in the case when you develop for the screen with a specific resolution. If you look at such application on the other screen, all the elements will be shifted and their positioning will be different from what you have planned. That’s why it is not recommended to use this Layout. And it’s compatibility with future Android versions is not guaranteed.

Saturday, March 12, 2016

Lesson 5. Layout-file for Activity. XML Representation. Changing screen orientation

In this lesson we will rotate the screen. The 2.3.3 version emulator, which we have successfully used and will be using for testing our applications further, has a bug. It doesn’t rotate the screen correctly.That’s why, please remember lesson 3 and create one more emulator of version 2.2, for instance. When creating a project specify Android version 2.2 as well. Screenshots are made on version 2.3.3 - don’t pay attention to this.

Let’s create a new project:
Project name: P0051_LayoutFiles
Build Target: Android 2.2Application name: LayoutFilesPackage name: ru.startandroid.develop.LayoutFilesCreate Activity: MainActivity
In development, every Activity has a corresponding java-class (subclass of android.app.Activity). When the application runs and the system has to display Activity and to work further with it, it will invoke methods of this class. And Activity behaviour depends on the content of these methods.
When creating a project we specified that Activity named MainActivity must be created.
When using the old wizard it looked like this:

In the new wizard - slightly different. Tick on one screen, name on the other:

We asked to create an Activity and Eclipse has created a corresponding class for us (we will learn to create them by ourselves soon).
Let’s observe this class: double click the file src/ru.startandroid.develop.LayoutFiles/MainActivity.java
In our class we can see that onCreate method is implemented - it is invoked when the application creates and displays the Activity (ignore onCreateOptionsMenu for now). Let’s have a look at the implementation.
First line:super.onCreate(savedInstanceState); - superclass constructor that performs all the required procedures, we do not touch it.
We are interested in this code:setContentView(R.layout.main);
Method setContentView(int) sets the content of Activity from the layout-file. As an argument we specify not a path to our layout file (res/layout/main.xml), but a constant, which is the layout file ID. This constant is generated automatically here gen/ru.startandroid.develop.LayoutFiles/R.java.
You can open and view this file, but you shouldn’t change it. In the R class all the generated IDs for all project resources (from res/* folder) will be stored, so we could refer to them. Names of these constants are the same as resource file names (without extensions).

Let’s open res/layout/main.xml and see what’s inside

Let’s run the application and see what happens
Everything is correct - Activity displays what is specified in main.xml.
Let’s try to display the content of another file. Let’s create one more layout-file, myscreen.xml for instance. To do so, select a res/layout folder in our project and click the button for creating a new file.

The wizard will open
In the File field enter the name of the file: myscreen.xml and click Finish.
New layout file should open instantly. Add a TextView and change its text to "This screen is described not in main.xml, but in myscreen.xml" in Properties.
Now Eclipse will underline this text in yellow and complain saying something like this: [I18N] Hardcoded string "...", should use @string resource. It is disturbed by hardcode here. It wants us to use resource files for all the inscriptions. But for now, we don’t know how to do this, so ignore this warnings.
It is obligatory to save the file for the new constant to appear for this file - R.layout.myscreen.
Now let’s configure Activity to use new myscreen.xml file instead of main.xml. Open MainActivity.java and change setContentView method argument. Change "R.layout.main" for "R.layout.myscreen" (ID of the new layout-file). It should be like this:

Save and run the application. We can now see that it displays the content of myscreen.xml, because we explicitly specified it in setContentView method, which is invoked when Activity is created (onCreate).

Layout-file in XML representation

When you open main.xml you see it’s visual representation. It’s some kind of preview of how it will look on the screen. Below you can see two tabs - Graphical Layout andmain.xml. Open main.xml

We see quite readable xml-description of all View elements in our layout-file. Names of xml-elements are classes of View-elements and xml-attributes are parameters of View-elements, which we change in Properties tab. You can also make changes right here and they will be displayed in the Graphical Layout. For example, change a text in a TextView. Instead of link to a constant, specify your own text "Some text".
Save the file. Open Graphical Layout and view the changes.
Usually, book authors present the content of layout-files in xml representation. It is convenient - you can just copy the fragment and use it, and you don’t have to add View-elements manually and to look through Properties and configure everything manually. I will do the same way in my projects.

Layout-file when changing screen orientation

By default we configure layout-file for vertical screen orientation. But what will happen if we rotate the smartphone and horizontal orientation turns on. Let’s have a look.
Change myscreen.xml Let’s add a vertical row of buttons and change the inscription.
xml-code (you can copy and paste it into your file)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Vertical screen orientation">
</TextView>
<LinearLayout
 android:id="@+id/linearLayout1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical">
<Button
 android:id="@+id/button1"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button1">
</Button>
<Button
 android:id="@+id/button2"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button2">
</Button>
<Button
 android:id="@+id/button3"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button3">
</Button>
<Button
 android:id="@+id/button4"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button4">
</Button>
</LinearLayout>
</LinearLayout>
Note that I’ve added vertical LinearLayout and put four buttons inside. We will discuss it in the next lesson in more detail.
Run the application. Everything is fine in vertical orientation.
Press CTRL+F12 in the emulator, screen orientation changed to horizontal and our buttons do not fit the screen any more (version 2.3.3 emulator has glitches and screen orientation change doesn’t always work).

So we need one more layout-file, which will be made for horizontal orientation and in our case will display buttons horizontally.
But how can we notify Activity, that in vertical orientation it has to use one layout-file and in horizontal - another? Android creators have already solved this issue for us. We must create a res/layout-land folder, and create a layout-file inside with the same name as in res/layout folder. This file will be used in horizontal orientation.
Create a folder: right click on res, New > Folder, Folder name = layout-land, click Finish.
Then we will create res/layout-land/myscreen.xml file and configure it for landscape orientation. Identically as the first time, click the button for file creation. The wizard will open.
Enter the name of the file: myscreen.xml
The wizard can complain that the destination file already exists - The destination file already exists. That’s because it looks at earlier created res/layout/myscreen.xml file. We have to specify that the new file must go into res/layout-land folder, not res/layout. Click Next.

And here just manually add the suffix -land to get res/layout-land

As a variant, we were able not to add the suffix manually, but to add Orientation attribute from the left column and specify it the value Landscape. Wizard would have understood everything right and added the -land suffix by itself.
We have added the path manually and wizard added the attribute to the right.
Click Finish and the file is now ready.
Put this xml-code into the file and save it to get the same screen as above.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Horizontal screen orientation">
</TextView>
<LinearLayout
 android:id="@+id/linearLayout1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="horizontal">
<Button
 android:id="@+id/button1"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button1">
</Button>
<Button
 android:id="@+id/button2"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button2">
</Button>
<Button
 android:id="@+id/button3"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button3">
</Button>
<Button
 android:id="@+id/button4"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:text="Button4">
</Button>
</LinearLayout>
</LinearLayout>

Run the application. Activity reads the layout-file, which we specified as a parameter in setContentView - myscreen.xml and displays its content. Switch the orientation CTRL+F12. Activity understands that it is in horizontal orientation now, it looks for myscreen.xml in the layout-land folder and uses it.

In this lesson we:
explored how Activity knows which layout file to read and configured Activity to read another file
observed layout-file from the other side - XMLfound out, which layout-file is used when screen orientation changes (horizontal/vertical)
  1. ANDROID TRAINING IN KATHMANDU
  2. ANDROID TRAINING IN LALITPUR 
  3. APP DEVELOPMENT IN KATHMANDU

Friday, March 11, 2016

Lesson 4. Layout elements and their properties

If to compare with Windows, the application consists of windows, which are called Activities. Usually, only one Activity is displayed at a time and it occupies the whole screen. And application switches between Activities. We can explore mail app as an example. One Activity displays a list of messages, the second one - displays a specific message and the third one - mailbox settings. While working with mail you switch between these Activities.
The content of Activity is composed of different components, so called Views. The most widely used Views are buttons, text input fields, checkboxes etc.
It can be displayed approximately like this:
Note, that a View is usually situated in a ViewGroup. The most common example of ViewGroup is Layout. Layouts can be of different types and they are responsible for placing its child elements - Views on the screen (in table, row, column ...).
You can read about this in more detail in help: User Interface and Common layout Objects
I am sure that I’ve already confused you with new words and terms, so let’s review all of this in practice. Create a project with the following properties:

Project name: P0041_BasicViews
Build Target: Android 2.3.3Application name: BasicViewsPackage name: ru.startandroid.develop.BasicViewsCreate Activity: MainActivity
If you have the latest version of project creation wizard, then Build Target is the same thing as Build SDK. In the Activity creation screen don’t forget to enter main in the Layout Name field.

In our project we are interested in res > layout > main.xml file
It is a layout-file. In this file we will define a set of View elements, which we want to see on the screen, and their location on it. When the application starts, Activity reads this file and displays us what we have configured there. Let’s open it and have a look which View set does it contain by default. 
On the left we can see a list of Views divided in groups. You can see here all the View-elements that you can use in your application.
It may have different appearance, which can be configured in the Palette menu a little bit to the top.

Glance at the white screen. We can see that now on the screen is present an element with “Hello World!” text. To find out what View it is, click on this text. In the Outline tab on the right you will notice all the elements defined in main.xml.
 We can see that the element we’ve just selected is a TextView. Note, that it’s inside RelativeLayout element, which is a ViewGroup. I’ve mentioned about ViewGroups above.
Let’s add some more elements on the screen. let it be a Button and a CheckBox. To do so, just drag and drop them from the list on the left to the white screen of your future application. You can also drag and drop them to the RelativeLayout in the Outline tab. The result will be almost the same. Let’s also add to the screen Plain Text from the Text Fields group, besides Button and CheckBox.
They will appear with names button1checkBox1 and editText1 in the Outline. These are IDs that have been assigned automatically. Let’s leave them as they are for now, later we will learn how to change them and will make them more meaningful.
Now we have a few elements on our screen. Let’s change their inscriptions. Click on TextView in the Outline tab. Now we need Properties tab. It displays selected in Outline or on the screen  View-element’s properties. It is usually situated just below the Outline.
Let’s find a Text property in Properties. At the moment there is a link to a String constant. We will review where to create constants in the next lessons, but for now, let's enter a custom text here: “Some text”.

Let's change Text property for button1, checkBox1, and editText1 elements to custom text. All these changes are written into main.xml. Let's save everything CTRL+SHIFT+S and launch the application CTRL+F11.
The application displays MainActivity, which reads main.xml file and displays all the Views that we have created and configured.

In this lesson we:
have found out what is displayed on Android application screen.
learnt how to form a layout file - add Views and configure their properties.