安卓学习笔记之五:Android Studio_骰子案例3(Kotlin搭配 Jetpack Compose实现)

使用 Compose 创建一款交互式 Dice Roller Android 应用。

完成:

  • 定义可组合函数。
  • 使用组合创建布局。
  • 使用 Button 可组合项创建按钮。
  • 导入 drawable 资源。
  • 使用 Image 可组合项显示图片。
  • 使用可组合项构建交互式界面。
  • 使用 remember 可组合项将组合中的对象存储到内存中。
  • 使用 mutableStateOf() 函数刷新界面以创建可观察对象。

一 创建项目 

  1. 在 Android Studio 中,依次点击 File > New > New Project
  2. 在 New Project 对话框中,选择 Empty Activity,然后点击 Next
  3. 在 Name 字段中,输入 Dice Roller
  4. 在 Minimum SDK 字段中,从菜单中选择最低 API 级别 24 (Nougat),然后点击 Finish

 二 创建布局基础架构

主布局初始代码如下:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MyApplicationTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {Greeting("Android")}}}}
}@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {Text(text = "Hello $name!",modifier = modifier)
}@Preview(showBackground = true)
@Composable
fun GreetingPreview() {MyApplicationTheme {Greeting("Android")}
}

仿真运行,可以看到 Hello Andriod输出。

1 重构示例代码

您需要更改一些生成的代码,使其更贴近 Dice Roller 应用的主题。

如您在最终应用的屏幕截图中看到的那样,应用中有骰子的图片和用于掷骰子的按钮。您将构建可组合函数以反映此架构。

如需重构示例代码,请执行以下操作:

  • 移除 DefaultPreview() 函数。
  • 创建一个带有 @Composable 注解的 DiceWithButtonAndImage() 函数。

该可组合函数代表布局的界面组件,还包含按钮点击和图片显示逻辑。

  • 移除 Greeting(name: String) 函数。
  • 创建一个带有 @Preview 和 @Composable 注解的 DiceRollerApp() 函数。

由于该应用仅包含一个按钮和一张图片,因此不妨将该可组合函数视为应用本身。因此,我们称之为 DiceRollerApp() 函数。 

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

由于移除了 Greeting() 函数,因此 DiceRollerTheme() lambda 正文中对 Greeting("Android") 的调用会突出显示为红色。这是因为编译器无法再找到对该函数的引用。

删除 onCreate() 方法中的 setContent{} lambda 内的所有代码。

  • 在 setContent{} lambda 正文中,调用 DiceRollerTheme{} lambda,然后在 DiceRollerTheme{} lambda 内调用 DiceRollerApp() 函数。
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {DiceRollerTheme {DiceRollerApp()}}}
}
  • 在 DiceRollerApp() 函数中,调用 DiceWithButtonAndImage() 函数。
@Preview
@Composable
fun DiceRollerApp() {DiceWithButtonAndImage()
}

 2 添加修饰符

Compose 使用 Modifier 对象,该对象是用于修饰或修改 Compose 界面元素行为的元素的集合。您将使用该对象来设置 Dice Roller 应用组件的界面组件样式。

如需添加修饰符,请执行以下操作:

  • 将 DiceWithButtonAndImage() 函数修改为接受 Modifier 类型的 modifier 实参,并为其分配默认值 Modifier。
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
}

 

该函数允许传入 modifier 形参。modifier 形参的默认值为 Modifier 对象,因此是方法签名的 = Modifier 部分。借助某个形参的默认值,未来调用该方法的任何调用方都可以决定是否为该形参传递值。如果它们传递自己的 Modifier 对象,则可以自定义界面的行为和装饰。如果它们选择不传递 Modifier 对象,系统会假定使用默认值,即普通的 Modifier 对象。您可以将这种做法应用于任何形参。如需详细了解默认实参,请参阅默认实参。

  • 现在,DiceWithButtonAndImage() 可组合项具有修饰符参数,请在调用该可组合项时传递修饰符。由于 DiceWithButtonAndImage() 函数的方法签名已更改,因此在调用该方法时,应传入包含所需装饰的 Modifier 对象。Modifier 类负责对 DiceRollerApp() 函数中的可组合对象进行装饰或向其添加行为。在本例中,需要向传递到 DiceWithButtonAndImage() 函数的 Modifier 对象添加一些重要的装饰。
  • 将 fillMaxSize() 方法链接到 Modifier 对象,以便让布局填充整个屏幕。
  • 将 wrapContentSize() 方法链接到 Modifier 对象,然后传递 Alignment.Center 作为实参以将组件居中。Alignment.Center 会指定组件同时在水平和垂直方向上居中。

这样,fun DiceRollerApp()函数的最终代码如下:

@Preview
@Composable
fun DiceRollerApp() {DiceWithButtonAndImage(modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.Center))
}

 注意

  • import androidx.compose.ui.Modifier 语句会导入 androidx.compose.ui.Modifier 软件包,以便您引用 Modifier 对象。
  • fllMaxSize() 和 wrapContentSize() 的 import 语句分别是 import androidx.compose.foundation.layout.fillMaxSize 和 import androidx.compose.foundation.layout.wrapContentSize。
  • Alignment 对象的 import 语句为 import androidx.compose.ui.Alignment。

三 创建垂直布局 

在 Compose 中,垂直布局是使用 Column() 函数创建的。

Column() 函数是一种可组合项布局,它会按垂直序列放置其子级。在预期的应用设计中,骰子图片应该垂直显示在掷骰子按钮的上方。

如需创建垂直布局,请执行以下操作:

  • 在 DiceWithButtonAndImage() 函数中,添加一个 Column() 函数。
  • 将 modifier 实参从 DiceWithImageAndButton() 方法签名传递给 Column() 的修饰符实参。modifier 实参可确保 Column() 函数中的可组合项遵守对 modifier 实例调用的约束条件。
  • 将 horizontalAlignment 实参传递给 Column() 函数,然后将其值设为 Alignment.CenterHorizontally。这可以确保列中的子项相对于宽度在设备屏幕上居中。

 

fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {Column (modifier = modifier,horizontalAlignment = Alignment.CenterHorizontally) {}
}

四 添加按钮

  • 在 strings.xml 文件中,添加一个字符串并将其设为 Roll 值。
  • 在 Column() 的 lambda 正文中,添加 Button() 函数。
  • 在 MainActivity.kt 文件中,将 Text() 函数添加到函数 lambda 正文中的 Button()。
  • 将 roll 字符串的字符串资源 ID 传递到 stringResource() 函数,并将结果传递到 Text 可组合项。 

strings.xml 文件: 

<string name="roll">Roll</string>

 

fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
Column(modifier = modifier,horizontalAlignment = Alignment.CenterHorizontally) {Button(onClick = { /*TODO*/ }) {Text(stringResource(R.string.roll))}}    
}

五 添加图片

应用的另一个重要组件是骰子图片,在用户点按 Roll 按钮后,该图片会显示结果。

1 导入图片

预先准备好 6 个骰子图片文件,都是200*250dp,其骰子点数分别为 1 到 6。

将其放到项目目录\app\src\main\res\drawable下。

2 添加 Image 可组合项 

骰子图片应显示在 Roll 按钮上方。Compose 本身会依序放置界面组件。也就是说,哪个可组合项声明在先,就会先行显示。这意味着,首先声明的可组合项会显示在之后声明的可组合项的上面或前面。Column 可组合项中的可组合项会在设备上按上下顺序显示。在该应用中,您将使用 Column 来垂直堆叠可组合项,因此首先在 Column() 函数中声明的可组合项会先于同一 Column() 函数中之后才声明的可组合项显示。

如需添加 Image 可组合项,请执行以下操作:

  • 在 Column() 函数正文中,在 Button() 函数前面创建一个 Image() 函数。
  • 向 Image() 函数传递一个 painter 实参,然后为其分配接受可绘制资源 ID 实参的 painterResource 值。目前,请传递以下资源 ID:R.drawable.dice_1 实参。
  • 每当您在应用中创建图片时,都应该提供所谓的“内容说明”。内容说明是 Android 开发的重要组成部分。内容说明能够向各界面组件添加说明,以提高无障碍性。如需详细了解内容说明,请参阅描述每个界面元素。您可以将内容说明作为形参传递到图片。 

这样,fun DiceWithButtonAndImage()函数体就变为

Column(modifier = modifier,horizontalAlignment = Alignment.CenterHorizontally
) {Image(painter = painterResource(R.drawable.dice_1),contentDescription = "1")Button(onClick = { /*TODO*/ }) {Text(stringResource(R.string.roll))}
}

预览画面为: 

 

注意

  • Image 可组合项的 import 语句为 import androidx.compose.foundation.Image。

 六 构建掷骰子逻辑

现在所有必要的可组合项均已存在,接下来您可以修改应用,以便用户能点按按钮来掷出骰子 

1 将 Button 设为可交互

  • 在 DiceWithButtonAndImage() 函数中的 Column() 函数前面,创建一个 result 变量并将其值设为等于 1。
  • 查看 Button 可组合项。您会发现,系统正在向它传递一个 onClick 形参,该形参已设为内含 /*TODO*/ 注释的一对大括号。在本例中,大括号代表所谓的“lambda”,大括号内的区域是 lambda 正文。将函数作为实参进行传递时,相应过程也可称为回调。
  • 在 Button() 函数中,从 onClick 形参的 lambda 正文的值中移除 /*TODO*/ 注解。
  • 掷骰子是随机的。为了在代码中反映这一点,您需要使用正确的语法来生成随机数字。在 Kotlin 中,您可以对一个数字范围使用 random() 方法。在 onClick lambda 正文中,将 result 变量的范围设为 1 到 6,然后针对该范围调用 random() 方法。请注意,在 Kotlin 中,范围由范围中的第一个数字与范围中的最后一个数字之间的两个句点指定。  
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {var result = 1Column(modifier = modifier,horizontalAlignment = Alignment.CenterHorizontally) {Image(painter = painterResource(imageResource), contentDescription = result.toString())Button(onClick = { result = (1..6).random() }) {Text(stringResource(R.string.roll))}}
}

现在,该按钮可点按了,但点按该按钮并不会产生任何可见的变化,因为您仍需构建该功能。

 2 为 Dice Roller 应用添加条件

  • 将 result 变量设为 remember 可组合项。remember 可组合项需要传递函数。
  • 在 remember 可组合项正文中,传入 mutableStateOf() 函数,然后向该函数传递 1 实参。mutableStateOf() 函数会返回一个可观察对象。稍后,您会详细了解可观察对象,但目前这基本上意味着,当 result 变量的值变化时,系统会触发重组、反映结果值并刷新界面。
  • 在 result 变量实例化的下方,创建一个不可变的 imageResource 变量,并将其设为接受 result 变量的 when 表达式,然后将每个可能的结果设为其可绘制对象。 
  • 将传递到 Image 可组合项的 painterResource 形参的 ID 从 R.drawable.dice_1 可绘制对象更改为 imageResource 变量。
  • 通过将 result 变量转换为包含 toString() 的字符串并将其作为 contentDescription 传递,更改 Image 可组合项的 contentDescription 形参以反映 result 变量的值。

这样,fun DiceWithButtonAndImage()函数的最终代码如下:

@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {var result by remember {mutableStateOf(1)}Column (modifier = modifier,horizontalAlignment = Alignment.CenterHorizontally) {val imageResource = when (result) {1 -> R.drawable.dice_12 -> R.drawable.dice_23 -> R.drawable.dice_34 -> R.drawable.dice_45 -> R.drawable.dice_5else -> R.drawable.dice_6}Image(painter = painterResource(id = imageResource),contentDescription = result.toString())Button(onClick = { result = (1..6).random() }) {Text(stringResource(R.string.roll))}}
}

 

七 运行应用。

现在,Dice Roller 应用应该完全可以正常运行了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/472663.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线Windows鼠标主题转换器(ani动态鼠标改为Xcur)

文章目录 前言在哪访问如何使用惨淡的界面简单粗暴的使用方法目前的bug 前言 在这篇文章中&#xff0c;我使用一些方法把转换脚本包装成了在线服务&#xff0c;现在我将说明如何使用服务。 在哪访问 还是说明一下&#xff0c;访问链是这个&#xff1a;https://www.sakebow.c…

【python】python入门(变量名)

Hi~ o(*&#xffe3;▽&#xffe3;*)ブ今天一起来看看python入门之变量名吧~~ 变量名的规定&#xff1a; 举个例子&#xff1a; “违法”的变量名们 my love/my &#xff01;love错误&#xff1a;中间不能是空格或者其他符号1my_love错误&#xff1a;不能数字开头"my_l…

蓝桥杯第十四届电子类单片机组程序设计

目录 前言 蓝桥杯大赛历届真题&#xff08;点击查看&#xff09; 一、第十四届比赛题目 1.比赛原题 2.题目解读 1&#xff09;任务要求 2&#xff09;注意事项 二、任务实现 1.NE555读取时机的问题 1&#xff09;缩短计数时间 2&#xff09;实时读取 2.温度传感器读…

Qt for android : Qt6.6.2 搭建 环境

环境说明 参考Qt助手: Assistant 6.6.2 (MinGW 11.2.0 64-bit) ***Gradle : Gradle wrapper, version 8.3***JDK11 SDK Tools / NDK 25.1.8937393 参考 Qt For Android : Qt5.13.1 Qt for android: Qt6.4搭建环境遇到的几个问题

.NET高级面试指南专题八【 垃圾回收机制GC】

.NET的垃圾回收&#xff08;Garbage Collection&#xff0c;简称GC&#xff09;是一种自动内存管理机制&#xff0c;负责在运行时追踪和释放不再使用的对象&#xff0c;以避免内存泄漏和提高应用程序的性能。 垃圾回收的基本原理&#xff1a; 标记阶段&#xff08;Mark Phase&…

前端工程化面试题 | 12.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

机器学习面试:请你谈谈生成模型和判别模型的区别?

生成模型:由数据学习联合概率密度分布P(XY)&#xff0c;然后求出条件概率分布P(YIX)作为预测的模型&#xff0c;即生成模型:P(Y|X) P(X,Y)/ P(X)(贝叶斯概率)。基本思想是首先建立样本的联合概率概率密度模型P(X,Y)然后再得到后验概率P(Y|X)&#xff0c;再利用它进行分类。典型…

RK3568笔记十七:LVGL v8.2移植

若该文为原创文章&#xff0c;转载请注明原文出处。 本文介绍嵌入式轻量化图形库LVGL 8.2移植到Linux开发板ATK-RK3568上的步骤。 主要是参考大佬博客&#xff1a; LVGL v8.2移植到IMX6ULL开发板_lvgl移植到linux-CSDN博客 一、环境 1、平台&#xff1a;rk3568 2、开发板:…

python实现多图绘制系统

文章目录 需求和框架AxisFrameAxisListDarwSystem 从零开始实现一个三维绘图系统 需求和框架 本文希望实现下图所示的绘图系统&#xff0c;下面详细分析需求变化。 和之前实现的绘图系统相比&#xff0c;首先是多了【新增】和【删除】这两个按钮&#xff0c;其功能是控制绘图数…

游戏安全组件运行时发生异常1-0-0

可能是这个服务&#xff0c;可能被禁用了。 如果是文件缺少直接修复游戏

Android 12.0 MTK Camera2 设置默认拍照尺寸功能实现

1.前言 在12.0的系统rom定制化开发中,在mtk平台的camera2关于拍照的一些功能修改中,在一些平台默认需要设置最大的分辨率 来作为拍照的分辨率,所以就需要了解拍照尺寸设置流程,然后来实现相关的功能 如图: 2.MTK Camera2 设置默认拍照尺寸功能实现的核心类 \vendor\me…

[NSSRound#16 Basic]Web

1.RCE但是没有完全RCE 显示md5强比较&#xff0c;然后md5_3随便传 md5_1M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&md5_2M%C9h%FF%0E%E3%5C%20%95r%D4w…