Android App Development Course in Kotlin, Various Dialogs

In Android app development, a dialog is a very important element that interacts with users. Dialogs are used to convey information to users or to receive input from users. Let’s explore how to implement various types of dialogs using Kotlin.

Types of Dialogs

  • Alert Dialog: A dialog that displays a simple message to the user and requires a selection.
  • Single Choice Dialog: A dialog that allows the user to select one option from multiple choices.
  • Multi Choice Dialog: A dialog that allows the user to select multiple options from several choices.
  • Input Dialog: A dialog that contains a text field for user input.

1. Alert Dialog

An alert dialog allows the user to confirm important information and make a selection. Below is an example of implementing an alert dialog.


private fun showAlertDialog() {
    val builder = AlertDialog.Builder(this)
    builder.setTitle("Alert")
    builder.setMessage("This app was developed in Kotlin.")
    builder.setPositiveButton("OK") { dialog, which -> 
        Toast.makeText(this, "The OK button was clicked.", Toast.LENGTH_SHORT).show()
    }
    builder.setNegativeButton("Cancel") { dialog, which -> 
        dialog.dismiss()
    }
    val dialog: AlertDialog = builder.create()
    dialog.show()
}

The above code demonstrates how to create and display an alert dialog. Using AlertDialog.Builder, you can set the dialog’s title, message, and buttons. The actions to be taken when the user clicks the buttons can also be defined.

2. Single Choice Dialog

A single choice dialog is a dialog that allows the user to select one option among multiple options. Here is an example of implementing a single choice dialog.


private fun showSingleChoiceDialog() {
    val items = arrayOf("Option 1", "Option 2", "Option 3")
    var selectedItem = 0

    val builder = AlertDialog.Builder(this)
    builder.setTitle("Single Choice Dialog")
    builder.setSingleChoiceItems(items, selectedItem) { dialog, which ->
        selectedItem = which
    }
    builder.setPositiveButton("Select") { dialog, which ->
        Toast.makeText(this, "Selected option: ${items[selectedItem]}", Toast.LENGTH_SHORT).show()
    }
    builder.setNegativeButton("Cancel") { dialog, which -> 
        dialog.dismiss()
    }
    builder.show()
}

This code creates a single choice dialog that allows the user to select an option. The option selected by the user is stored in the selectedItem variable, and the selected option is displayed when the positive button is clicked.

3. Multi Choice Dialog

A multi choice dialog is a dialog that allows the user to select multiple options from several choices. Below is an example of a multi choice dialog.


private fun showMultiChoiceDialog() {
    val items = arrayOf("Option A", "Option B", "Option C")
    val checkedItems = booleanArrayOf(false, false, false)

    val builder = AlertDialog.Builder(this)
    builder.setTitle("Multi Choice Dialog")
    builder.setMultiChoiceItems(items, checkedItems) { dialog, which, isChecked ->
        // The value of 'isChecked' is true when the user selects an option.
    }
    builder.setPositiveButton("Select") { dialog, which ->
        val selectedOptions = StringBuilder("Selected options: ")
        for (i in items.indices) {
            if (checkedItems[i]) {
                selectedOptions.append(items[i]).append(" ")
            }
        }
        Toast.makeText(this, selectedOptions.toString(), Toast.LENGTH_SHORT).show()
    }
    builder.setNegativeButton("Cancel") { dialog, which -> 
        dialog.dismiss()
    }
    builder.show()
}

This dialog allows users to select multiple options. The checkedItems array tracks the selection status of each option, and selected options are displayed when the positive button is clicked.

4. Input Dialog

An input dialog is a dialog that allows users to input text. Here is an implementation example of an input dialog.


private fun showInputDialog() {
    val builder = AlertDialog.Builder(this)
    builder.setTitle("Input Dialog")

    val input = EditText(this)
    builder.setView(input)

    builder.setPositiveButton("OK") { dialog, which ->
        val userInput = input.text.toString()
        Toast.makeText(this, "Entered text: $userInput", Toast.LENGTH_SHORT).show()
    }
    builder.setNegativeButton("Cancel") { dialog, which -> 
        dialog.dismiss()
    }
    builder.show()
}

The above code shows a dialog that allows the user to enter text. The text entered by the user is stored in the userInput variable when the positive button is clicked, allowing for various operations to be performed with it.

Conclusion

In this tutorial, we explored how to implement various dialogs using Kotlin in Android. We learned how to effectively interact with users through alert dialogs, single choice, multi choice dialogs, and input dialogs. Dialogs are important elements that enhance user experience, so using them appropriately can help develop more attractive apps.

For more diverse uses of dialogs, it is recommended to refer to the official Android documentation or study related books for in-depth knowledge.

Кotlin Android App Development Course, Creating a News App

Kotlin has established itself as a powerful and modern programming language for Android app development. This course will guide you step-by-step on how to create a real news app using Kotlin. The app is designed to fetch news from an external API and display it to users. Through this article, you will learn about Android application architecture, networking, UI/UX design, and other essential features.

1. Project Setup

The first step of this project is to set up a new project in Android Studio. First, open Android Studio and start a new project.

  • Project Name: NewsApp
  • Package Name: com.example.newsapp
  • Language: Kotlin
  • Device: Phone and Tablet
  • API Level: API 21: Android 5.0 (Lollipop)

Once the project is created, open the AndroidManifest.xml file and add the internet permission as shown below.

<uses-permission android:name="android.permission.INTERNET" />

2. Select News API

Select the API to be used for creating the news app. Here, we will use NewsAPI. It returns results in JSON format and is structured to be easy to use.

To obtain an API key, please sign up on the site and generate an API key.

3. Add Networking Library

We’ll manage network requests using Retrofit from Android Jetpack. Add the Retrofit library to the build.gradle file.

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
}

Sync the Gradle file.

4. Create Data Model Classes

Create data classes to map the data fetched from the news API. Create classes called Article and NewsResponse.

data class Article(
    val source: Source,
    val author: String?,
    val title: String,
    val description: String?,
    val url: String,
    val urlToImage: String?,
    val publishedAt: String,
    val content: String?
)

data class Source(
    val id: String?,
    val name: String
)

data class NewsResponse(
    val status: String,
    val totalResults: Int,
    val articles: List<Article>
)

5. Define Retrofit Interface

Define the Retrofit interface to communicate with NewsAPI. This will allow you to configure HTTP requests.

interface NewsApiService {
    @GET("v2/top-headlines")
    suspend fun getTopHeadlines(
        @Query("country") country: String = "us",
        @Query("apiKey") apiKey: String
    ): NewsResponse
}

6. Create Retrofit Instance

Create a Retrofit instance to prepare for API calls. Use the Singleton pattern to manage the instance.

object RetrofitInstance {
    private const val BASE_URL = "https://newsapi.org"

    private val retrofit by lazy {
        Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(BASE_URL)
            .build()
    }

    val api: NewsApiService by lazy {
        retrofit.create(NewsApiService::class.java)
    }
}

7. Utilize ViewModel and LiveData

To apply the MVVM pattern, use ViewModel and LiveData to separate the UI from the data. Create a ViewModel to manage the news data.

class NewsViewModel(private val apiKey: String) : ViewModel() {
    private val _news = MutableLiveData<List<Article>>()
    val news: LiveData<List<Article>> get() = _news

    fun fetchTopHeadlines() {
        viewModelScope.launch {
            val response = RetrofitInstance.api.getTopHeadlines(apiKey = apiKey)
            _news.postValue(response.articles)
        }
    }
}

8. Design UI

Modify the layout file of MainActivity to add a RecyclerView. Below is an example of activity_main.xml.

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:listitem="@layout/item_article"/>

Create a layout item_article.xml to display each news item.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop"/>

    <TextView
        android:id="@+id/titleTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:padding="8dp"/>

    <TextView
        android:id="@+id/descriptionTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:padding="8dp"/>

</LinearLayout>

9. Configure RecyclerView Adapter

Implement RecyclerView.Adapter to display news data on the screen.

class NewsAdapter(private val articles: List<Article>) : RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {

    inner class NewsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val titleTextView: TextView = itemView.findViewById(R.id.titleTextView)
        val descriptionTextView: TextView = itemView.findViewById(R.id.descriptionTextView)
        val imageView: ImageView = itemView.findViewById(R.id.imageView)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_article, parent, false)
        return NewsViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
        val currentArticle = articles[position]
        holder.titleTextView.text = currentArticle.title
        holder.descriptionTextView.text = currentArticle.description
        // Image loading is handled by libraries like Glide or Picasso
    }

    override fun getItemCount() = articles.size
}

10. Data Binding in MainActivity

Set up the RecyclerView in MainActivity and fetch data through the ViewModel.

class MainActivity : AppCompatActivity() {
    private lateinit var newsViewModel: NewsViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)

        val apiKey = "YOUR_API_KEY" // Enter your API key
        newsViewModel = ViewModelProvider(this, ViewModelFactory(apiKey)).get(NewsViewModel::class.java)

        newsViewModel.fetchTopHeadlines()
        newsViewModel.news.observe(this, { articles ->
            val adapter = NewsAdapter(articles)
            recyclerView.adapter = adapter
        })
    }
}

11. Improve User Interface

Add click events to each news item so that users can navigate to the article’s URL when they click on it.

class NewsAdapter(private val articles: List<Article>, private val context: Context) : RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {
    inner class NewsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val titleTextView: TextView = itemView.findViewById(R.id.titleTextView)
        val descriptionTextView: TextView = itemView.findViewById(R.id.descriptionTextView)
        val imageView: ImageView = itemView.findViewById(R.id.imageView)

        init {
            itemView.setOnClickListener {
                val position: Int = adapterPosition
                val article = articles[position]
                val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(article.url))
                context.startActivity(browserIntent)
            }
        }
    }
}

12. Changing User Experience

Add a ProgressBar to improve the app’s user experience, informing users about the loading progress when retrieving data.

<ProgressBar
    android:id="@+id/progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"/>

Modify the MainActivity code to show the ProgressBar during data loading and hide it when loading is complete.

newsViewModel.news.observe(this, { articles ->
    progressBar.visibility = View.GONE
    recyclerView.adapter = NewsAdapter(articles, this)
})

// Show ProgressBar before data loading
progressBar.visibility = View.VISIBLE

Summary and Conclusion

In this course, we explored the entire process of creating a news app using Kotlin. You had the opportunity to learn essential to advanced techniques needed for real app development, including setting up Retrofit for network communication, managing data with the MVVM architecture, and using RecyclerView. Additionally, you can improve the design or extend features to provide a better user experience.

You are now ready to create your own news app! Practice it yourself and try adding various features.

Kotlin Android App Development Course, Navigation View – Drawer Screen Composition

Android provides several ways to manage screen transitions when creating multi-page applications. One popular method is the Navigation View. In this article, we will delve into how to set up a drawer screen through the Navigation View.

1. What is Navigation View?

The Navigation View is a UI component that helps users easily navigate between different sections of the app. It typically appears by sliding in from the left side of the screen and can be opened by clicking on the hamburger icon at the top or by swiping.

2. Advantages of Navigation View

  • Intuitive Navigation: It clearly displays various sections available for selection, making navigation easy.
  • Space Efficiency: It remains hidden by default and only appears when needed, enhancing screen utilization.
  • Consistent UI: It provides a consistent user experience across various screen configurations.

3. Setting Up Navigation View

Step 1: Project Setup

Open Android Studio and create a new project. Select “Empty Activity” to start with a basic structure. Choose Kotlin as the language, set the package name and save location, then click “Finish” to create the project.

Step 2: Configure Gradle Dependencies

Add the necessary dependencies to use the Navigation View. Open the project’s build.gradle file and add the following library:

    
    dependencies {
        implementation 'com.google.android.material:material:1.5.0'
    }
    

The library above supports Material Design components. Be sure to apply the changes via Gradle Sync afterward.

Step 3: Create XML Layout

Edit the layout file of the main activity, activity_main.xml, to add the Navigation View. Below is an example of the basic structure:

    
    <androidx.drawerlayout.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Main Content"
                android:layout_gravity="center"/>

        </FrameLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/nav_menu"/>

    </androidx.drawerlayout.widget.DrawerLayout>
    

Step 4: Create Navigation Menu

Set up the required menu items for the Navigation View. Create a res/menu/nav_menu.xml file and add the following content:

    
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/nav_home"
            android:title="Home"/>
        <item
            android:id="@+id/nav_profile"
            android:title="Profile"/>
        <item
            android:id="@+id/nav_settings"
            android:title="Settings"/>
    </menu>
    

Step 5: Connect Navigation View and Activity

Modify the MainActivity.kt file to connect the Navigation View and main activity. Below is an example that includes basic code:

    
    package com.example.navigationdrawer

    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import androidx.drawerlayout.widget.DrawerLayout
    import com.google.android.material.navigation.NavigationView
    import androidx.appcompat.widget.Toolbar
    import android.view.MenuItem
    import android.content.Intent

    class MainActivity : AppCompatActivity() {

        private lateinit var drawerLayout: DrawerLayout
        private lateinit var navView: NavigationView

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            val toolbar: Toolbar = findViewById(R.id.toolbar)
            setSupportActionBar(toolbar)

            drawerLayout = findViewById(R.id.drawer_layout)
            navView = findViewById(R.id.nav_view)

            navView.setNavigationItemSelectedListener { menuItem ->
                when (menuItem.itemId) {
                    R.id.nav_home -> {
                        // Handle home click
                        true
                    }
                    R.id.nav_profile -> {
                        // Handle profile click
                        true
                    }
                    R.id.nav_settings -> {
                        // Handle settings click
                        true
                    }
                    else -> false
                }.also {
                    drawerLayout.closeDrawers() // Close the drawer
                }
            }
        }
    }
    

Step 6: Opening and Closing the Drawer

To open or close the drawer, you need to use user interface elements. It is typically set up to open the drawer by clicking on the hamburger icon in the Toolbar. Add the following code to MainActivity.kt:

    
    toolbar.setNavigationOnClickListener {
        drawerLayout.openDrawer(GravityCompat.START)
    }
    

The above code opens the drawer when the navigation icon (hamburger icon) in the drawer layout is clicked.

4. Managing Multiple Fragments

Let’s also learn how to manage multiple Fragments with the Navigation View. Fragments are independent modules that make up the UI and can be reused across different screen configurations.

Step 1: Create Fragment Classes

First, create Fragment classes. For example, let’s create “HomeFragment”, “ProfileFragment”, and “SettingsFragment”:

    
    class HomeFragment : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return inflater.inflate(R.layout.fragment_home, container, false)
        }
    }

    class ProfileFragment : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return inflater.inflate(R.layout.fragment_profile, container, false)
        }
    }

    class SettingsFragment : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return inflater.inflate(R.layout.fragment_settings, container, false)
        }
    }
    

Step 2: Create Fragment Layout Files

You need to create layout files for each Fragment. Below are examples of XML layout files for each Fragment:

    
    <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:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Home Screen"/>
    </LinearLayout>

    <!-- profile.xml -->
    <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:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Profile Screen"/>
    </LinearLayout>

    <!-- settings.xml -->
    <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:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Settings Screen"/>
    </LinearLayout>
    

Step 3: Handle Fragment Transitions

Write code to switch to the corresponding Fragment when a menu item is clicked. Modify the navView.setNavigationItemSelectedListener part in MainActivity.kt:

    
    navView.setNavigationItemSelectedListener { menuItem ->
        val fragment: Fragment = when (menuItem.itemId) {
            R.id.nav_home -> HomeFragment()
            R.id.nav_profile -> ProfileFragment()
            R.id.nav_settings -> SettingsFragment()
            else -> HomeFragment()
        }
        supportFragmentManager.beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commit()
        drawerLayout.closeDrawer(GravityCompat.START)
        true
    }
    

5. Optimizing Navigation View

There are several methods to optimize the app’s performance. For example, using asynchronous tasks or data caching techniques can make the UI smoother.

Conclusion

You have learned how to use the Navigation View in Android app development with Kotlin to provide an excellent user experience. The Navigation View is one of the essential elements in modern Android apps and is very useful for implementing various user interfaces. I hope you will actively use the Navigation View in your future development processes!

References

kotlin android app development course, looking at basic views

In Android app development, a “View” is the most basic component of the User Interface (UI). In this course, we will take a closer look at the basic views of Android apps using Kotlin. We will learn about the types and characteristics of views, as well as how to utilize them through actual example code.

1. Understanding Views

A view is an element that allows users to interact with the app. It serves the role of displaying information (text, images, etc.) to the user or collecting user input. There are various views provided in Android, all of which inherit from the View class.

Commonly used views include:

  • TextView: A view that displays text on the screen.
  • EditText: A view that allows users to enter text.
  • Button: A button that can be clicked by the user.
  • ImageView: A view that displays images.
  • CheckBox: A checkbox that can be selected.
  • RadioButton: A radio button that allows selecting one option among multiple choices.
  • ListView: A view that displays multiple items in a list format.

2. Basic View Example

Now, let’s create a simple Android app using basic views. In this example, we will implement an app that receives user input through TextView, EditText, and Button, displaying the entered text in TextView upon button click.

2.1. Project Setup

Create a new project in Android Studio. Please follow the settings below:

  • Select Project: Empty Activity
  • Select Language: Kotlin
  • Select Minimum API level: API 21: Android 5.0 (Lollipop)

2.2. Layout Configuration

Once the project is created, open the res/layout/activity_main.xml file and update it as follows:


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="The entered text will be displayed here."
        android:textSize="24sp"/>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter text here"/>

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Display Text"/>

</LinearLayout>

2.3. Implementing MainActivity Class

Now, navigate to the MainActivity.kt file and add logic to change the text upon button click:


package com.example.myapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView

class MainActivity : AppCompatActivity() {

    private lateinit var textView: TextView
    private lateinit var editText: EditText
    private lateinit var button: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        textView = findViewById(R.id.textView)
        editText = findViewById(R.id.editText)
        button = findViewById(R.id.button)

        button.setOnClickListener {
            textView.text = editText.text
        }
    }
}

2.4. Running the App

Now, when the app is run, the text entered by the user in EditText will be displayed in TextView upon clicking the button.

3. Properties and Uses of Various Views

In addition to the basic views discussed above, we will look at various other views, their properties, and how to handle events.

3.1. TextView

TextView has various properties. The most commonly used properties are:

  • text: Sets the text.
  • textSize: Sets the size of the text.
  • textColor: Sets the color of the text.
  • gravity: Sets the alignment of the text.

<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Hello!"
    android:textSize="18sp"
    android:textColor="#FF6347"
    android:gravity="center"/>

3.2. EditText

EditText is a view that can receive user input and can be configured with additional properties such as input format.

Commonly used properties:

  • hint: Provides a hint in the input field.
  • inputType: Sets the format of input (e.g., text, number, email, etc.).

<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Enter email"
    android:inputType="textEmailAddress"/>

3.3. Button

A Button is a view that can handle events, allowing for various background colors, text colors, etc.

Additionally, buttons in Android can handle click events to perform various actions. To do this, the setOnClickListener method is used.

3.4. CheckBox and RadioButton

A CheckBox allows multiple options to be selected, while a RadioButton allows only one option to be selected from multiple choices.

For example, you can use CheckBox and RadioButton like this:


<CheckBox
    android:id="@+id/checkBox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Option 1"/>

<RadioGroup
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    
    <RadioButton
        android:id="@+id/radioButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Option A"/>

    <RadioButton
        android:id="@+id/radioButton2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Option B"/>

</RadioGroup>

4. Event Handling

All views have methods that can handle various events. The basic events that can be handled include:

  • OnClickListener: Handles click events.
  • OnLongClickListener: Handles long click events.
  • TextWatcher: Detects changes in text.

4.1. Button Click Event

To define an action when the button is clicked, you can use the setOnClickListener method. In the MainActivity.kts file, you can handle the button click event as follows:


button.setOnClickListener {
    // Code to execute when the button is clicked
    Toast.makeText(this, "Button was clicked.", Toast.LENGTH_SHORT).show()
}

4.2. Using TextWatcher

You can use TextWatcher to detect changes whenever the user types text in EditText. Here is an example of how to implement it:


editText.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        // Code to handle when the text changes
    }

    override fun afterTextChanged(s: Editable?) {}
})

5. Types of Layouts

In Android, there are various layouts in which views can be arranged. The following layouts are frequently used:

5.1. LinearLayout

LinearLayout is a layout that allows views to be arranged vertically or horizontally. The orientation property can be used to set the direction.


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    ...
</LinearLayout>

5.2. RelativeLayout

RelativeLayout is a layout that allows you to set the relative position between views. You can position a view based on the position of another view.


<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="Positioned at the top"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView"
        android:text="Positioned below the button"/>

</RelativeLayout>

5.3. ConstraintLayout

ConstraintLayout is a layout that helps in easily constructing complex layouts. It allows you to set constraints between views for flexible placement.


<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Hello!"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click"
        app:layout_constraintTop_toBottomOf="@id/textView"
        app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

6. Advanced Views and Custom Views

In addition to the built-in views, you can create custom views in Android to meet specific functionality or design requirements of your app.

6.1. Creating a Custom View

The following example explains how to create a custom view. First, create a new Kotlin class that inherits from the View class:


import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View

class CustomView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private val paint = Paint()

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        paint.color = Color.BLUE
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
    }
}

Once you create the class above, you can use the custom view in the XML layout file:


<com.example.myapp.CustomView
    android:layout_width="match_parent"
    android:layout_height="200dp"/>

7. Conclusion and Deployment

We have now learned about basic views and their utilization. I hope you have gained an understanding of the foundational elements needed to create a real app. In the next lesson, we will cover more complex views and implementations of lists and graphs using various adapters.

Of course, once your app is complete, you need to prepare for deployment through Google Play. Before distribution, it is essential to thoroughly test the app and improve it based on user feedback.

I hope this article has been helpful, and I encourage you to continue your interest and efforts in Android app development using Kotlin.

Building Android Apps with Kotlin: Utilizing Google Maps

In modern mobile application development, map functionality has become an essential component. Especially for apps that provide location-based services (e.g., food delivery, travel guides, etc.), using Google Maps is very useful. In this tutorial, we will detail how to implement Google Maps in Android apps using Kotlin.

1. Understanding the Google Maps API

The Google Maps API is a service that allows developers to integrate Google Maps into their applications. Through this API, various features such as location display, route navigation, and user current location can be utilized.

2. Setting Up Android Studio Environment

To integrate Google Maps into your Android app, you first need to set up the development environment. Let’s start a new project using Android Studio.

  1. Open Android Studio and create a new project.
  2. When creating the project, select Empty Activity.
  3. After setting the project name and package name, proceed to the next step.

3. Obtaining the Google Maps API Key

You need an API key to use Google Maps. Here, I will explain how to obtain the API key.

  1. Visit the Google Cloud Platform and create a new project.
  2. Activate the Maps API in the API & Services menu.
  3. Create an API key, which you will use to send requests.
  4. Add the API key to the res/values/strings.xml file:
<string name="google_maps_key">YOUR_API_KEY</string>

4. Adding Dependencies to Gradle

You need to add the necessary dependencies to the build.gradle file to use Google Maps.

dependencies {
    implementation 'com.google.android.gms:play-services-maps:17.0.1'
}

5. Creating XML Layout File

To display the map in the app, you can add a MapView or SupportMapFragment to the XML layout file. Here, we will use SupportMapFragment. Create the res/layout/activity_maps.xml file as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </fragment>

</RelativeLayout>

6. Creating Map Activity

Now, it’s time to create an activity to display Google Maps. Create the MapsActivity.kt file as follows:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

    private lateinit var mMap: GoogleMap

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap

        // Add a marker in Sydney and move the camera
        val sydney = LatLng(-34.0, 151.0)
        mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
    }
}

7. Requesting App Permissions

To use location information, you need to add the required permissions to the app’s AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application
    ... >
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />
</application>

8. Displaying Current Location on Map

Let’s add functionality to display the current location on the app. Add the code to enable user location in the onMapReady method:

if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    // If permission is not granted
    ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), 1000)
    return
}
mMap.isMyLocationEnabled = true

9. Pinpointing User Location

In addition to adding the basic location, you can implement functionality to pin a specific location when the user selects it. Add the following code to the onMapClickListener method:

mMap.setOnMapClickListener { latLng ->
    mMap.addMarker(MarkerOptions().position(latLng).title("Selected Location"))
}

10. Additional API Features

The Google Maps API provides various features beyond simple map display. For example, drawing routes, adding multiple markers, or creating custom markers. Below is an example of creating a custom marker:

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.custom_marker)
val markerOptions = MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromBitmap(bitmap))
mMap.addMarker(markerOptions)

11. Testing and Deployment

Once the app is complete, you can test it on an emulator or a real device. After ensuring there are no issues, you will prepare it for distribution on the Play Store. To distribute, create an APK file and upload it via the Play Console.

Conclusion

In this tutorial, we learned how to utilize Google Maps in Android apps using Kotlin. The Google Maps API offers various and powerful features, so take advantage of it to develop location-based services. Through various examples and exercises, we hope you become a better developer.

If you found this tutorial helpful, please share it and leave a comment! We are preparing a series of more Android development tutorials, so stay tuned.