Hello Android With Kotlin
Learning Android is a lot less intimidating when you are introduced to the basics. Here are the basics I was taught recently by following a free Udacity tutorial to build a dice roller app (a link to it is at the end). Also, this post doesn't really have a lot of Kotlin specific, but is more geared toward understanding a very basic Android App.
Getting Started
Starting to dive into unfamiliar tech can be overwhelming, luckily, there's really not that much prerequisite to getting started with Android.
What you need
Personal opinion, you'll want to have a computer that is fairly powerful and has plenty of RAM to spare. I've heard Android Studio can potentially be a resource hog, but it's not a requirement to have a beast of a machine.
Actual Needs
- Download the latest version of Android Studio
- Android Device - Android Studio does provide you an emulator if you don't have a physical device.
Create a Project
Once you've got Android Studio installed you can create a project, which, actually sets up an entire "Hello World!" for you with a layout file, a kotlin file, and more.
- Start up Android Studio
- Follow the prompts to create a new Project
- For simplicity, start with a Blank Activity (it's as basic as it gets)
- In one section of the options you can choose either java or kotlin, I'm choosing kotlin.
- With your first app, most of the options can, and should, be left at defaults.
After you've created your first project it might take a few minutes to build as it sets up all the files. Once your files are all generated see Run Your App in Google's docs to get a device set up.
At this point you can hit the play button in the IDE and it will build, install, and launch your app on the emulator or physical device, whichever you have set up. And it will give you the all too common "Hello World!" on your screen, but it's really fun to see it pop up on your phone! (I use a real device)
File Structure
Once your project has built, you can finally take a peek at the file structure. For me, it helps to at least be aware of what the folders are, even if I don't need to touch them yet.
It's good to understand the magic going on so you can really own your project
In the left side of the IDE you'll see the files of your new project. You'll also notice at the top area above the files, it has a dropdown to select different views of the project's files.
- Project: Shows the files as they are in the filesystem. (This view is good to know about, but less useful in my short time with it)
- Android: Shows a friendly view of the various folders which house different content. Note - it's NOT the actual folder structure of the files on disk, it's just organized in this way to be useful for developers.
- (others I've not explored yet)
Moving forward in my Android experience I will be using the Android view as it seems to be the easiest to work with, until I find some reason not to.
Here are the essential folders to be aware of in your project (there are lots more).
- manifests: Essential app details the OS needs to launch your app.
- java: All kotlin/java code to control your app goes here
- java(generated): Files generated by the IDE, there's no need to modify these files
- res: Folders with resources you can use in your app
- drawable: contains images/vectors
- layout: contains xml files that describe screens of your app
- values: contains strings, and other static values
Key Parts of Android
In the most basic app, I learned that there are really 3 basic building blocks to get something working in an Android App. There's the xml layout, the controlling java/kotlin Activity code, and optionally some resources to reference, like strings.
If you are in the Android View of your project they are in these folders
- xml layouts -> app/res/layout
- activities -> app/java
- resources -> app/res
Layout (XML)
This is where you actually build the components that the user will see. It's defined in XML, and there are many different components you can place into the layout. I will introduce you to a few by sharing my _activitymain.xml layout file so you can see what one looks like, but rather than seeing all the details, let's start without all the Android specifics.
Let's start by how you can think about the design of a layout. In a simple app, lets say we want just a few elements that appear 1 by 1 vertically
Paragraph of text
Image
Button to press and respond to
Now that we know what we want, we just need to search in the docs for what can give us the functionality we want. After finding the XML elements that match your needs lay them out in XML.
- LinearLayout gives me the vertical 1 by 1 I want if I place elements inside of it
- TextView shows text
- ImageView shows an image
- Button is an Android button for interactions
{% raw %}
<LinearLayout>
<TextView/>
<ImageView/>
<Button/>
</LinearLayout>
{% endraw %}
Now that we know the elements we need, we'll need to research and fill in all the Android details, (or just follow a tutorial that teaches them to you 👍)
Here's what it looks like all filled out, some was boilerplate, some was manual injection by me, but it's important to see the structure is what I thought up before even thinking in Android's terms.
{% raw %}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/roll_description"
android:textAlignment="center"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:src="@drawable/your_image"
tools:src="@drawable/your_design_image"
android:id="@+id/action_image"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/roll"
android:id="@+id/roll_button"/>
</LinearLayout>
{% endraw %}
Very concise recap... We have a ViewGroup LinearLayout element, holding the other elements that give us the layout we thought up, now with Android details.
I feel it might be worth going over some of the android attributes, because when I see them, it feels overwhelming.
First, the root element of a layout can specify what namespaces are used with the xmlns attributes. I'm not going to claim I know a lot about these, but here's what I'm using in the LinearLayout (root) element so I can use the attributes from those namespaces.
- xmlns:android="http://schemas.android.com/apk/res/android" provides android attributes
- xmlns:tools="http://schemas.android.com/tools" provides build time tools, and the usages of it are removed from elements during build time of your app.
- xmlns:app="http://schemas.android.com/apk/res-auto" in my usage provides backwards compatibility for the ImageView to draw vector graphics. I followed the tutorial on this one, and definitely need to research to understand this more.
android attributes
- layout_width: the width of your element
- layout_height: the height of your element
- orientation: vertical | horizontal for LinearLayout
- layout_gravity: where to position the view/element
- text: display text
- gravity: helps align the contents of the view/element
- id: This is used to allow your kotlin/java code to reference the element to do something with it. If you want that button to do something, the id attribute is essential.
- When declaring an id, do it like this _android:id="@+id/your_idname". Under the hood Android Studio will create an integer id for you to reference using the R class in your Activity code (I'll show you this later).
Activity (Kotlin)
An activity file is where you actually define the behavior of the app. For example...
- You can define what happens when a button is clicked by the user.
- Should text appear at the bottom of the screen confirming to the user that something happened?
- Randomly generate a number, like a dice roll
- etc
Ok, so at it's core, we want our user to click the button, and have something happen. You'd add something like this to your Activity in it's onCreate() method (probably app/java/[your package name]/MainActivity.kt if you just created your project)
// Using findById, get reference to a button
val actionButton: Button = findViewById(R.id.your_button_id)
// tell it what to do when clicked
actionButton.setOnClickListener {
// Your actions go here, be creative!
// Create a message
// Change some text of an existing element
// Generate a number
// Have fun with it...
}
There are a lot of things you can do, I'll leave it to you to look up what's possible. If you want something simple, you could look at using a Toast() popup 👍
Resources (images/text)
I want to go over the two resources I used, images, and strings. The larger your projects gets, the more you'll gather up, so it's good to know how they're used.
Images
Images that you want to use in your app go in the drawable folder. Simply copy your images into the res/drawable folder and then you can reference the image in your layout xml files.
<ImageView android:src="@drawable/your_image" />
String Resource (located at app/res/values/strings.xml)
The strings resource files has contents like this, which you can either enter manually, or, you can use the IDE helper lightbulb to place it in for you (very handy).
<resources>
<string name="app_name">Your App Name Goes Here</string>
<string name="roll">Seek Your Fate!</string>
<string name="roll_description">Each day of life is a roll of the dice... Make the best of it no matter what you get!</string>
</resources>
Use strings in your layouts like this. It will grab the string from the strings.xml file and place them into the view for you. This is nice because it keeps your xml layout file more concise, especially if you have paragraphs of text.
<TextView android:text="@string/roll_description" />
Gradle Build System
I mostly wanted to mention this because it really does feel like a magic box that puts everything together. Gradle provides these features for your app, I'll leave a link to their site at the end if you want to learn more.
- Target particular Android devices
- Compiles your app to executable code
- Dependency management
- App Signing for Google Play
- Automated Tests
There is a .gradle file for
- Each module of your app
- Your entire project
Industry Tips
There were a couple things mentioned in the Udacity course that I'd love to pass along.
- Reduce Calls to findViewById. If at all possible reduce the calls to findViewById, it can be an expensive operation and cause lag if misused.
- Always move strings to the resource file. The makes it easier to deal with all of your strings because they are all in one place, especially if you want to translate your app to other languages
- View Binding - The instructor had notes recommending using this instead of using findViewById. They mentioned these advantages.
- You get a reference to the full xml layout, and can still reference the id you need
- Type Safety, you don't have to guess what type a view element is
- Null Safety, you don't pass a resource number, so you can't guess wrong
Conclusion
That was a LOT of information, even as I read back over my post I realize how much of a wall of information it was. Hopefully you might have picked up a few things you didn't know before, let me know if you did find it helpful!