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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi