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

本文主要是介绍安卓学习笔记之五: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 应用应该完全可以正常运行了!

这篇关于安卓学习笔记之五:Android Studio_骰子案例3(Kotlin搭配 Jetpack Compose实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717398

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库