Android Basics
Introduction to the Android framework and basic concepts
Updated: 03 September 2023
From the Android Docs and this section
Creating a Project
- Download and install Android Studio
- Create a new Empty Activity Project with Kotlin selected as the language and make use of
androidx.*artifacts
Android Studio should now set up the initial project
| Name | My First App |
|---|---|
| Package | com.nabeelvalley.myfirstapp |
| Save Location | C:\Repos\AndroidStudio\MyFirstApp |
| Language | Kotlin |
| Minimum API Level | API Level 15: Android 4.0.3 |
Use androidx.* artifacts |
After creating the app there should be a gradle download which may take a while
Generated Files and Structure
There are a couple of different files that are generated in the application directory that we created. The files relevant to the application development are contained in the app/src directory
- The first relevant file is the
MainActivity.ktfile which is the application’s entrypoint and is in theapp/java/com.nabeelvalley.myfirstappdirectory, the code in this file can be seen below:
1package com.nabeelvalley.myfirstapp2
3import androidx.appcompat.app.AppCompatActivity4import android.os.Bundle5
6class MainActivity : AppCompatActivity() {7
8 override fun onCreate(savedInstanceState: Bundle?) {9 super.onCreate(savedInstanceState)10 setContentView(R.layout.activity_main)11 }12}- Next is the
app/res/activity_main.xmlfile which is the layout file for the Main Activity, this contains a simpleTextViewwrapped in aConstraintLayoutwhich can be seen below:
1<?xml version="1.0" encoding="utf-8"?>2<androidx.constraintlayout.widget.ConstraintLayout3 xmlns:android="http://schemas.android.com/apk/res/android"4 xmlns:tools="http://schemas.android.com/tools"5 xmlns:app="http://schemas.android.com/apk/res-auto"6 android:layout_width="match_parent"7 android:layout_height="match_parent"8 tools:context=".MainActivity">9
10 <TextView11 android:layout_width="wrap_content"12 android:layout_height="wrap_content"13 android:text="Hello World!"14 app:layout_constraintBottom_toBottomOf="parent"15 app:layout_constraintLeft_toLeftOf="parent"16 app:layout_constraintRight_toRightOf="parent"17 app:layout_constraintTop_toTopOf="parent" />18
19</androidx.constraintlayout.widget.ConstraintLayout>- Then we have the
AndroidManifest.xmlfile which contains information about the application and define’s its components. It’s a manifest - pretty normal
1<?xml version="1.0" encoding="utf-8"?>2<manifest xmlns:android="http://schemas.android.com/apk/res/android"3 package="com.nabeelvalley.myfirstapp" >4
5 <application6 android:allowBackup="true"7 android:icon="@mipmap/ic_launcher"8 android:label="@string/app_name"9 android:roundIcon="@mipmap/ic_launcher_round"10 android:supportsRtl="true"11 android:theme="@style/AppTheme" >12 <activity android:name=".MainActivity" >13 <intent-filter>14 <action android:name="android.intent.action.MAIN" />15
16 <category android:name="android.intent.category.LAUNCHER" />17 </intent-filter>18 </activity>19 </application>20
21</manifest>- Additionally there are
build.gradlefiles for different parts of the application that are used by Gradle to build the application
Running the App
To run the application on a device you will need to do the following:
- Enable USB Debugging on your device
- Install your device drivers, information here
Note if using a Huawei you need to use HiSuite which should show up as a drive when your device is plugged in, you may then neeed to run
- On Android Studio click on
File > Sync Project with Gradle Files, this will ensure that the correct debugging options show up in the debug toolbar - In the Debuging toolbar click on the Run button, this should show a list of devices and you can select your device from here
Editing the UI
The UI is built using XML, however it can also be edited through the Android Studio Layout Editor which is probably easier for now. Different components are called Views and these are contained in ViewGroups
To view the Layout Editor do the following:
- Open the
app/res/layout/activity_main.xmlfile - Click the
Designtab at the bottom of the window if you see the XML - Click
Select Design Surfaceand selectBlueprint
In the Component Tree you will see that the main wrapper is a ConstraintLayout which contains a TextView object
A ConstraintLayout is a layout that defines the positioning of each child based on constraints to its siblings, this avoids some needs for a nested layout which can take longer to draw to the screen
We can add a Text Box with the following steps
- Remove the current
TextViewelement by clicking on the Component Tree and then clicking Delete - From the
Textsection of the component list drag anEditTextcomponent onto the screen, this is a text box that accepts plain text input - Click and drag the anchors (or dots) in the middle of the top edge to the top of the screen and the left to the left edge of the screen to create a constraint
- In the
Layoutsection of the attributes (should be on the right) set the margins to16dp
Next add a Button onto the screen and then do the following
- Add a
16dpconstraint from the left side to theEditText - Right click on the
Buttonand clickShow Baseline - Drag a constraint from
Button’s Baseline to theEditText’s Baseline
You should notice the different attributes of the elements on the right side of the screen, these can be edited
Now let’s make the text box responsive:
Shift + Cickto select the two elementsRight Clickto open the menu and selectChains > Create Horizontal Chain
A chain is a bidirectional constraint that allows you to lay out children in a group
- Select the button and set the right margin to
16dp - From the Layout menu on the
EditTextand click twice on the horizontal constraints and set them to beMatch Constraints
String Localization
We can add localizations for strings by adding them to the app/res/values/strings.xml file directly or using the Translations Editor
- Open the
strings.xmlfile and on the top right clickOpen Editorand then the+at the left to create a new value - Use the Translation Editor to create the following values
| Key | Default Value |
|---|---|
message_edit | Enter a Message |
button_submit | Submit |
The Resulting XML file should contain the following:
1<resources>2 <string name="app_name">My First App</string>3 <string name="message_edit">Enter a Message</string>4 <string name="button_submit">Submit</string>5</resources>Next we can apply the strings to our field and button from the Design View/Editor
- Select the layout element
- In the
textproperty delete the value and click on icon to the right and select the correct string resource for the field
The resulting layout should be as follows:
1<?xml version="1.0" encoding="utf-8"?>2<androidx.constraintlayout.widget.ConstraintLayout3 xmlns:android="http://schemas.android.com/apk/res/android"4 xmlns:tools="http://schemas.android.com/tools"5 xmlns:app="http://schemas.android.com/apk/res-auto"6 android:layout_width="match_parent"7 android:layout_height="match_parent"8 tools:context=".MainActivity">9 <EditText10 android:layout_width="0dp"11 android:layout_height="wrap_content"12 android:inputType="textShortMessage"13 android:ems="10"14 android:id="@+id/editText" android:layout_marginTop="16dp"15 app:layout_constraintTop_toTopOf="parent" android:layout_marginStart="16dp"16 app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="16dp"17 android:text="@string/message_edit" app:layout_constraintHorizontal_bias="0.5"18 app:layout_constraintEnd_toStartOf="@+id/button"/>19 <Button20 android:layout_width="wrap_content"21 android:layout_height="wrap_content"22 android:id="@+id/button" app:layout_constraintStart_toEndOf="@+id/editText" android:layout_marginLeft="16dp"23 android:layout_marginStart="16dp"24 app:layout_constraintBaseline_toBaselineOf="@+id/editText" android:text="@string/button_submit"25 app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toEndOf="parent"26 android:layout_marginRight="16dp" android:layout_marginEnd="16dp"/>27</androidx.constraintlayout.widget.ConstraintLayout>Handling Events
We can handle the click event on the Submit button by using an event handler in our MainActivity.kt file, we just need to add a handler function to the class
We can add something like:
1/** Called when the user taps the submit button */2fun handleSubmit(view: View) {3 // Do stuff4}We can then bind this to the onClick event on the Attributes list for the button. For a method to be compatible with the android:onClick attribute it must:
- Be publicly accessible
- Return
unitorvoid - Have a
Viewas its only parameter
Next, from the function we defined we can use the following to get the text value from the EditText
1val editText = findViewById<EditText>(R.id.editText)2val message = editText.text.toString()Note that you can click
Alt + Enterto resolve missing references
Next we can create an Intent for a second activity for which we will send the message to using the following code
1val intent = Intent(this, DisplayMessageActivity::class.java).apply {2 putExtra(EXTRA_MESSAGE_KEY, message)3}From the above we have the DisplayMessageActivity class that is not yet defined, this is the class for the activity we will create next. The putExtra function is used to store intent data as a key-value pair
The EXTRA_MESSAGE_KEY is defined above out class as a const
1const val EXTRA_MESSAGE_KEY = "com.example.myfirstapp.MESSAGE"And then we can start an activity with the intent using:
1startActivity(intent)The overall MainActivity.kt file should now be as follows
1package com.nabeelvalley.myfirstapp2
3import androidx.appcompat.app.AppCompatActivity4import android.content.Intent5import android.os.Bundle6import android.view.View7import android.widget.EditText8
9const val EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"10
11class MainActivity : AppCompatActivity() {12
13 override fun onCreate(savedInstanceState: Bundle?) {14 super.onCreate(savedInstanceState)15 setContentView(R.layout.activity_main)16 }17
18 /** Called when the user taps the submit button */19 fun handleSubmit(view: View) {20 val editText = findViewById<EditText>(R.id.editText)21 val message = editText.text.toString()22 val intent = Intent(this, DisplayMessageActivity::class.java).apply {23 putExtra(EXTRA_MESSAGE, message)24 }25 startActivity(intent)26 }27}Lastly from the design view from the activity_main.xml you should be able to select the handleSubmit option in the onClick dropdown which will set the handler to the function we created
Create a New Activity
From the Project Window right click on the app folder and select New > Activity > Empty Activity and call it DisplayMessageActivity
On the new activity add a TextField and change the id to messageDisplay
Now using the onCreate function we can add the following code to set the TextView to display the data we have from the EditText on the main screen
1// Get the Intent that started this activity and extract the string2val message = intent.getStringExtra(EXTRA_MESSAGE)3
4// Capture the layout's TextView and set the string as its text5val textView = findViewById<TextView>(R.id.messageDisplay).apply {6 text = message7}This leaves the resulting DisplayMessageActivity.kt file as follows:
1package com.nabeelvalley.myfirstapp2
3import androidx.appcompat.app.AppCompatActivity4import android.os.Bundle5import android.widget.TextView6
7class DisplayMessageActivity : AppCompatActivity() {8
9 override fun onCreate(savedInstanceState: Bundle?) {10 super.onCreate(savedInstanceState)11 setContentView(R.layout.activity_display_message)12
13 // Get the Intent that started this activity and extract the string14 val message = intent.getStringExtra(EXTRA_MESSAGE)15
16 // Capture the layout's TextView and set the string as its text17 val textView = findViewById<TextView>(R.id.messageDisplay).apply {18 text = message19 }20 }21}Lastly we need to add a button from the DisplayMessageActivity back to the MainActivity, we can do this from the AndroidManifest.xml by replacing the <activity> tag for the DisplayMessageActivity with the following to indicate the parent activity:
1<activity android:name=".DisplayMessageActivity"2 android:parentActivityName=".MainActivity">3 <!-- The meta-data tag is required if you support API level 15 and lower -->4 <meta-data5 android:name="android.support.PARENT_ACTIVITY"6 android:value=".MainActivity" />7</activity>Lastly we can run the application and we should be able to pass data between as well as navigate the two activities