🦁

【超初心者向け】お天気カード2

に公開
前回の記事はこちら

ボタンを押したときの処理の概要

「明日の天気は?」ボタンを押したとき、現在表示されている「?」カード以外のお天気カードが表示されるように変更していきます。
現在、画像表示している部分は、
Image(painter = painterResource(id = R.drawable.tenki0)・・・の部分です
tenki0の画像で固定されていますが、この部分がボタンを押すたびに変わってくれれば、やりたいことが達成できそうです!

画像表示部分を変数にする

Image(painter = painterResource(id = R.drawable.tenki0)・・・の太字部分を変数にしましょう。

  • varでrandomImage変数を作成。
     ボタンを押すたびにrandomImage変数の中身が変わるので、varで宣言。
    また、randomImageの値が変更したときに、画面を更新させるため、mutableStateOfで監視します。
    かっこの中身は初期値です。
     byとかrememberとかを説明すると、記事1本できそうなので、どこかで説明します😱
     var randomImage by remember { mutableStateOf(R.drawable.tenki0) }

  • リソース部分を変数に変更。
     Image(painter = painterResource(id = randomImage)・・・

変数について詳しく知りたい方はこちら
HomeScreen
@Composable
fun HomeScreen(modifier: Modifier = Modifier) { //引数にmodifierを設定
+    var randomImage = R.drawable.tenki0

    Column(
        modifier = modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ){
        Image(
+            painter = painterResource(id = randomImage),
            contentDescription = null,
            modifier = Modifier
                .padding(top = 120.dp)
                .size(360.dp)
                .aspectRatio(1f)
        )
        //省略

画像リストを作成

tenki1~6までの画像をランダムに選択するため、画像をリストにしましょう。

  • リストはlistOf(アイテム1,アイテム2,・・・・・)で作成します。
  • tenki0はリストに入れません。
    リストに入れるとtenki0も明日の天気に表示される可能性があるからです。
    @Composable
    fun HomeScreen(modifier: Modifier = Modifier) { //引数にmodifierを設定
        //画像を表示するリストを作成
+        val images = listOf(
+            R.drawable.tenki1,
+            R.drawable.tenki2,
+            R.drawable.tenki3,
+            R.drawable.tenki4,
+            R.drawable.tenki5,
+            R.drawable.tenki6,
+        )
        var randomImage = R.drawable.tenki0

これで、imagesという変数の中にリストが格納されました。

明日の天気は?ボタンを押したときの処理

ボタンをクリックしたときに、iamgesリストからランダムに1枚画像を選択し、randomImage変数に入れます。

  • ButtonのonClickのラムダ{}の中にrandomImage = images.random()を追加。
@Composable
fun HomeScreen(modifier: Modifier = Modifier) { //引数にmodifierを設定
    //省略
        Button(
+            onClick = { randomImage = images.random() },
            modifier= Modifier
                .padding(top = 100.dp)
                .size(width = 200.dp, height = 64.dp)
        ){
            Text(text="明日の天気は?",fontSize = 20.sp)
        }
    }
}

ボタンクリック時の処理が完成しました。
実行してボタンを押してみましょう!
画像変わりましたか?
6枚しかないので、クリックしても同じのが出る可能性があり、変わったかどうかわからない場合もありますので、数回クリックしてみてくださいね。
ここまでのコードを以下に表示します。

@Composable
fun HomeScreen(modifier: Modifier = Modifier) { //引数にmodifierを設定
    //画像を表示するリストを作成
    val images = listOf(
        R.drawable.tenki1,
        R.drawable.tenki2,
        R.drawable.tenki3,
        R.drawable.tenki4,
        R.drawable.tenki5,
        R.drawable.tenki6,
    )
    var randomImage by remember { mutableStateOf(R.drawable.tenki0) } //画像リストからランダムに画像を表示。初期値はtenki0
    Column(
        modifier = modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ){
        Image(
            painter = painterResource(id = randomImage),
            contentDescription = null,
            modifier = Modifier
                .padding(top = 120.dp)
                .size(360.dp)
                .aspectRatio(1f)
        )
        Button(
            onClick = { randomImage = images.random() },
            modifier= Modifier
                .padding(top = 100.dp)
                .size(width = 200.dp, height = 64.dp)
        ){
            Text(text="明日の天気は?",fontSize = 20.sp)
        }
    }
}

おまけのアニメーション

最後に、画像の変化があまりにもそっけないので、フェイドイン、フェイドアウトのアニメーションを入れてみました。
アニメーションするために変更した個所は緑の部分です。
アニメーションを非同期処理させるため、コルーチンスコープというものを使っています。
コルーチンについては別途説明したいと思います!(ああ。。。宿題がいっぱい><)

@Composable
fun HomeScreen(modifier: Modifier = Modifier) { //引数にmodifierを設定
    //画像を表示するリストを作成
    val images = listOf(
        R.drawable.tenki1,
        R.drawable.tenki2,
        R.drawable.tenki3,
        R.drawable.tenki4,
        R.drawable.tenki5,
        R.drawable.tenki6,
    )
    var randomImage by remember { mutableStateOf(R.drawable.tenki0) } 
+    var isShowImage by remember { mutableStateOf(true) }
+    val scope = rememberCoroutineScope()

    Column(
        modifier = modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ){
+        AnimatedVisibility(
+            visible = isShowImage,
+            enter = fadeIn(),
+            exit = fadeOut()
+        ) {
            Image(
                painter = painterResource(id = randomImage),
                contentDescription = null,
                modifier = Modifier
                    .padding(top = 120.dp)
                    .size(360.dp)
                    .aspectRatio(1f)
            )
+        }
        Button(
            onClick = {
+               isShowImage = false //画像をいったん非表示に
+               scope.launch {
+                   delay(300)      //アニメーションを待つ!
                    randomImage = images.random()
+                   isShowImage = true //画像を表示
                }
            },
            modifier= Modifier
                .padding(top = 100.dp)
                .size(width = 200.dp, height = 64.dp)
        ){
            Text(text="明日の天気は?",fontSize = 20.sp)
        }
    }
}

みなさまのやりたいことの一助となれば幸いです。
じゃぁまたね👋

Discussion