Jetpack Compose 投骰应用

淮城一只猫 编程技术 阅读量 0 评论量 0

前言

最近看了一些 Kotlin 基础知识没有过多做笔记,主要 KotlinTypeScript 语法太相似,所以基本都是跳着看,后续如果有问题再加深学习就行,最近间断性学习相关 Compose 组件布局,做了一个简单的交互界面应用,类似效果如下:

Screenshot_20230413_214231

编写布局

单纯来看其实也不算难,无非就是全局水平垂直居中即可:

@Composable
fun DiceWithButtonAndImage(
    modifier: Modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.Center)
) {
    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
				Image()
        Spacer(modifier = Modifier.height(16.dp))
        Button() {
            Text(stringResource(R.string.roll))
        }
    }
}
<resources>
    <string name="app_name">Dice Roller</string>
    <string name="roll">投!</string>
</resources>

Spacer 可以让图片和按钮之间塞入间隔,以免看起来太拥挤,大体来说也不算很难。

设计交互

现在需要做一个交互,就是点击 的按钮进行一个随机骰子,然后展示到图片上来。首先 Button 上面有个 onClick 这个属性来触发点击事件,利用随机限制 1 ~ 6 用图片展示出来即可:

var result = 1
result = (1..6).random()
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
    var result = 1
    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(painter = painterResource(imageResource), contentDescription = result.toString())
        Button(onClick = { result = (1..6).random() }) {
            Text(stringResource(R.string.roll))
        }
    }
}

上面这个操作可以点击交互,但是不能展示图片变化,需要做对应的条件处理,这里为了方便直接把随机值存储到内存里,利用 remember 存储到内存中:

var result by remember { mutableStateOf(1) }

mutableStateOf() 函数会返回一个可观察对象,当 result 变量的值变化时,系统会触发重组、反映结果值并刷新界面。

val imageResource = when (result) {
    1 -> R.drawable.dice_1
    2 -> R.drawable.dice_2
    3 -> R.drawable.dice_3
    4 -> R.drawable.dice_4
    5 -> R.drawable.dice_5
    else -> R.drawable.dice_6
}

然后根据判断条件整合到图片渲染:

Image(painter = painterResource(id = imageResource), contentDescription = result.toString())

代码如下:

package com.iiong.diceroller

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.iiong.diceroller.ui.theme.DiceRollerTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DiceRollerTheme {
                DiceRollerApp()
            }
        }
    }
}

@Composable
fun DiceWithButtonAndImage(
    modifier: Modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.Center)
) {
    var result by remember { mutableStateOf(1) }

    val imageResource = when (result) {
        1 -> R.drawable.dice_1
        2 -> R.drawable.dice_2
        3 -> R.drawable.dice_3
        4 -> R.drawable.dice_4
        5 -> R.drawable.dice_5
        else -> R.drawable.dice_6
    }

    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(id = imageResource),
            contentDescription = result.toString()
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { result = (1..6).random() }) {
            Text(stringResource(R.string.roll))
        }
    }
}

@Preview
@Composable
fun DiceRollerApp() {
    DiceWithButtonAndImage()
}
喵~