0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[チュートリアル5]世界各国の時間を表示するアプリを作る[compose multiplatform]

Last updated at Posted at 2023-11-30

はじめに

公式ドキュメントの和訳と要約+αです。
前回はこれです。

ページの基本要素を作る

composeApp/src/commonMain/kotlinのApp.ktを開いてください。

現在のコードを消して以下のコードを挿入してください。

@Composable
fun App() {
    MaterialTheme {
        var timeAtLocation by remember { mutableStateOf("No location selected") }
        Column {
            Text(timeAtLocation)
            Button(onClick = {
                timeAtLocation = "13:30"
            }) {
                Text("Show Time At Location")
            }
        }
    }
}

それに伴い以下のimportを挿入してください。

import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

簡単な解説

このレイアウトは、2つのコンポーザブルを含むカラム(列)です。最初のコンポーザブルはテキストで、2つ目はボタンです。

2つのコンポーザブルはtimeAtLocationプロパティを共有して持っています。
テキストコンポーザブルはこの状態のオブザーバー(監視者)なので、timeAtLocationプロパティの中身をリアルタイムで表示しています。
ボタンコンポーザブルはonClickハンドラーを使って、クリックされたらtimeAtLocationの中身に"13:30"を入れています。

ユーザーの入力を受け付けるようにする

ここでの目標は、ユーザーが都市名を入力すると、その場所の時刻が表示されるようにすることです。

そのためにユーザーが入力できるフォームをTextFiledコンポーザブルで実装します。

App.ktを以下の内容に書き換えてください。

@Composable
fun App() {
    MaterialTheme {
        var location by remember { mutableStateOf("Europe/Paris") }
        var timeAtLocation by remember { mutableStateOf("No location selected") }

        Column {
            Text(timeAtLocation)
            TextField(value = location, onValueChange = {
                location = it
            })
            Button(onClick = {
                timeAtLocation = "Time at $location is 13:30"
            }) {
                Text("Show Time At Location")
            }
        }
    }
}

importにはこれを追加してください。

import androidx.compose.material.TextField

簡単なコード解説

TextFieldとlocationプロパティを追加しました。
TextFieldは文字の入力フォームで、onValueChangeイベントハンドラーによって、文字が入力されるとその文字をlocationに代入します。
そのlocationをtimeAtLocationで使って、Textの中とかで使っています。

時間を計算する

ユーザーの入力を使って、表示する時間を計算します。そのためにcurrentTimeAt()というファンクションを作りましょう

currentTimeAt()

App.ktに戻って、以下のコードを追加します。
ファイルの一番下で大丈夫です。

fun currentTimeAt(location: String): String? {
    fun LocalTime.formatted() = "$hour:$minute:$second"

    return try {
        val time = Clock.System.now()
        val zone = TimeZone.of(location)
        val localTime = time.toLocalDateTime(zone).time
        "The time in $location is ${localTime.formatted()}"
    } catch (ex: IllegalTimeZoneException) {
        null
    }
}

それに伴って、以下のimport分も追加しましょう。

import kotlinx.datetime.Clock
import kotlinx.datetime.IllegalTimeZoneException
import kotlinx.datetime.LocalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime

currentAtTime()を使ってみる

App()コンポーザブルの中で先ほど作ったcurrentTimeAt()を使うように修正しましょう。

App.ktの29行目あたりに、

timeAtLocation = "Time at $location is 13:30"
こういう記述があると思います。
これを以下のように修正してください。

timeAtLocation = currentTimeAt(location) ?: "Invalid Location"

これによって、元々は固定で13:30を表示していたところに、currentTimeAtファンクションにlocationの値を渡した時の返り値を表示するようになります。

元々のチュートリアルはもうちょっとあるんですが、ちょっと長いのでここまで!

残りは次の記事でやります!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?