安卓学习笔记之五: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

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("