跳过正文

Android-Compose初步-摇骰子

·204 字·1 分钟
Android Web-Develop Android App
HYH
作者
HYH
一名专注于网络安全、渗透测试与 CTF 挑战的技术爱好者,热衷于记录实战经验、分享工具与技术,致力于持续学习与成长。
目录

前言
#

最近在学习Android app开发,用的是Kotlin语言,然而B站上面的视频质量并不是很高,大多数都是对编程无基础人员的基本语法教学。相比之下,我觉得Android官方的Developer开发者课程是很不错的。此文章就是根据Android Developer中的创建交互式Dice Roller(摇骰子)部分进行学习记录,使用的是Jetpack compose的ui开发框架。

环境
#

API版本:31(官方使用的是26,不过并没有什么影响)

关键点
#

Modifier
#

在Jetpack Compose框架中,每一个可组合函数都会有个自带的Modifier,用于修改其样式。具体来说就类似于html中的div容器,在此框架中每个函数都会自带一个容器,容器也是可以继承的,也就是说子对象可以使用父对象的容器特征。

例如在下面这个代码示例中,整体视窗大小是被指定为Modifier的fillMaxSize,也就是填充到最大尺寸(填充全屏)。不仅如此还可指定padding填充、背景颜色、以及填充权重等。。。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                 Surface(modifier = Modifier
                     .fillMaxSize(),
                     color = MaterialTheme.colorScheme.background) {
                     DiceWithButtonAndImage(modifier = Modifier
                         .fillMaxSize())
                 }
            }
        }
    }
}

Compose
#

在函数上方添加**@Compose注解,可以将函数声明为可组合**函数。声明后,就有点类似于html的盒子模型,可以进行组合嵌套。

@Composable
fun DiceWithButtonAndImage(modifier: Modifier) {
    Column(modifier=modifier,
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center) {

        Image(
            painter = painterResource(R.drawable.dic1),
            contentDescription = result.toString()
        )
        Button(onClick = {

        }) {
            Text(stringResource(R.string.roll),
                modifier=Modifier.height(16.dp))
        }

    }
}

在上面这段代码中,可以看到整体是一个column竖柱形的**“容器”,其中放置了一个图片和一个按钮。对于排列函数来说,可以指定其水平或垂直的Style**

解决方案
#

逻辑梳理
#

在未点击按钮之前,应该先展示一张骰子的图片(可以随机也可以固定),这里就用固定的方式来展示。

那么在Button点击之后,希望得到的效果就是,界面上的Image被替换。

但是如果直接使用变量覆盖的方式是无法实现的,因为在Button点击之前页面是已经加载好了的,点击后再修改Image的source是没有效果的。

基于内存管理
#

默认情况下,可组合函数是无状态的,这意味着它们不存储值,并且可随时被系统重组,从而导致值被重置。不过,Compose 提供了一种避免这种情况的便捷方式。可组合函数可以使用 remember 可组合函数将对象存储在内存中。

那么将骰子的值使用remember进行内存存储就行了

代码
#

import....

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                 Surface(modifier = Modifier
                     .fillMaxSize(),
                     color = MaterialTheme.colorScheme.background) {
                     DiceWithButtonAndImage(modifier = Modifier
                         .fillMaxSize())
                 }
            }
        }
    }
}

@Composable
fun DiceWithButtonAndImage(modifier: Modifier) {
    Column(modifier=modifier,
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.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
        }
        Image(
            painter = painterResource(imageResource),
            contentDescription = result.toString()
        )
        Button(onClick = {
            result = (1..6).random()
            Log.i("HYH", result.toString())
        }) {
            Text(stringResource(R.string.roll),
                modifier=Modifier.height(16.dp))
        }

    }
}

界面效果

Reply by Email