为Android构建现代应用——主体结构
创建Screents和ViewModels
在前面的章节中,我们已经分析了OrderNow项目的理论概念和我们将赋予的组织。
在本章中,我们将开始实现初始结构和模板,这将联接每一个应用程序的部分。
首先将添加以下带有各自视图模型的主屏幕:
• 首页
• 产品列表
• 产品详情
• 购物车
添加元素的一个例子如下图所示:
Sreens 和 ViewModels
我们将在应用程序中使用依赖管理器将每个ViewModel绑定到各自的屏幕上。为此,我们必须首先在应用程序中依赖Hilt。
implementation 'com.google.dagger:hilt-android:2.38.1' // Use the latest version kapt 'com.google.dagger:hilt-android-compiler:2.38.1' // Use the latest version
在依赖Hilt的过程后,将要求定义应用类型类,例如在我们的示例项目中,将定义为OrderNowApplication,如下:
@HiltAndroidApp class OrderNowApplication:Application() { }
注意:在androidmanifest .xml中注册OrderNowApplication类
<application
android:name=".main.OrderNowApplication"
android:allowBackup="true"
...>
此外,我们将 Navigation Compose依赖到项目中,这将允许View(Composable)在导航期间获得其各自ViewModel的实例:
dependencies {
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'
}
一旦在项目中正确地执行了前面的配置,我们就可以像这样将ViewModel注入View:
Home ViewModel:
@HiltViewModel
class HomeViewModel @Inject constructor() : ViewModel() {
...
}
Home Screen:
@Composable
fun HomeScreen(viewModel: HomeViewModel = hiltViewModel()
) {
...
}
每个屏幕都将通过Hilt依赖管理器与其相应的ViewModel相关联。到目前为止,我们已经集成了以下架构组件:Compose、Navigation和ViewModel。
这是Jetpack工具的完美组合,在后面的章节中,我们将看到它在移动开发中的潜力。
UI模式:TopAppBar和BottomAppBar
通过Scaffold组件,我们可以在应用程序中实现两种在Material Design中最常见的UI模式:TopAppBar和BottomAppBar。
Scaffold是一个详细的视图(composable),它将允许我们以以下方式实现这些模式:
Scaffold:
Scaffold(
topBar = {
TopAppBar { /* Top app bar content */ }
},
bottomBar = {
BottomAppBar { /* Bottom app bar content */ }
}
) { contentPadding -> 9 // Screen content
}
在代码片段中,我们定义了topBar,bottomBar,和(还未添加的)屏幕内容。
在Scaffold中,topBar和bottomBar部分是可选的;也就是说,可以省略其中一部分的定义。此外,在Scaffold中,我们可以声明两个更多的组件:
• scaffoldState
• snackbarHost
在下一章,我们将看到每个的用法。现在我们只定义topBar和bottomBar。 现在我们知道如何在我们的应用程序中包含这些UI模式,下一步就是创建代表TopAppBar和BottomAppBar的视图(Composables)。
我们将其组织在一个叫做patterns的目录中,并在其中添加了两个Views,OrderNowTopBar和OrderNowBottomBar,如下所示:
TopAppBar and BottomAppBar Composables:
OrderNowTopBar
OrderNowTopBar的实现很简单。我们最初只需要以以下方式实现它:
@Composable
fun OrderNowTopBar() {
TopAppBar(
title = {
Text(
text = stringResource(id = AppString.app_name),
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
},
backgroundColor = MaterialTheme.colors.background,
contentColor = contentColorFor(MaterialTheme.colors.background)
)
}
之前的实现还不包含返回选项等元素;然而,在后面的章节中添加“Back”到TopAppBar中,它将包含这样一个使用状态策略的导航选项。
OrderNowBottomBar
OrderNowBottomBar的实现可以更精细一些,因为我们需要包括屏幕之间的导航。但是,我们将把实现细节留到下一章。
现在,我们将包含一个没有导航的静态定义。
@Composable
fun OrderNowBottomBar() {val selectedIndex = remember { mutableStateOf(0) }BottomNavigation(backgroundColor = MaterialTheme.colors.background,contentColor = contentColorFor(MaterialTheme.colors.background),elevation = 10.dp) {BottomNavigationItem(icon = {Icon(imageVector = Icons.Default.Home, "")},label = { Text(text = "Home") },selected = (selectedIndex.value == 0),unselectedContentColor = Color.Gray,selectedContentColor = orange,onClick = {selectedIndex.value = 0})BottomNavigationItem(icon = {Icon(imageVector = Icons.Default.ShoppingCart, "")},label = { Text(text = "Cart") },selected = (selectedIndex.value == 1),unselectedContentColor = Color.Gray,selectedContentColor = orange,onClick = {selectedIndex.value = 1})}
}
在这个阶段,我们已经有了屏幕、视图模型和Scaffold的定义(其中包括OrderNowBottomBar和OrderNowTopBar)。
下一步是将所有的部分组合在一起,我们将在下一部分中做这个。
将所有元素整合在一起
第一项任务是创建一个名为main的目录。这个目录将是横向的,并将包含App的基类或结构。
在该目录中,我们放置Application类,移动MainActivity到那里,以及应用程序的主屏幕,我们将其命名为OrderNowScreen,如下图所示。
Main Components:
现在我们修改MainActivity.kt类,以便它将登录屏幕加载到OrderNowScreen应用程序,如下所示:
@AndroidEntryPoint
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {OrderNowScreen()}}
}
然后,在OrderNowScreen视图中,我们像这样定义应用程序的Scaffold:
@Composable
fun OrderNowScreen() {InitialSkeletonTheme {Surface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colors.background) {Scaffold(topBar = { OrderNowTopBar() },bottomBar = { OrderNowBottomBar() }) { contentPadding ->println(contentPadding)}}}
}
当您运行应用程序时,结果应该类似于以下图像:
总结
在本章中,我们已经构建了OrderNow项目的初始结构。
这里定义和实现的组件将是下一章继续讨论导航的基础。
随着我们阅读这些章节,我们将改进OrderNow的每个部分的实现,因此.我们的电子贸易将以最佳方式设计和实施。
源码:
class MainActivity4: ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{OrderNowScreen()}}
}
@Preview
@Composable
fun OrderNowScreen() {MyTestTheme {Surface(modifier = Modifier.fillMaxSize(),color=MaterialTheme.colors.background){Scaffold(topBar = {OrderNowTopBar()},bottomBar={ OrderNowBottomBar()}) {contentPadding ->println(contentPadding)}}}
}@Preview
@Composable
fun OrderNowBottomBar(){val selectedIndex =remember{ mutableStateOf(0)}BottomNavigation(backgroundColor = MaterialTheme.colors.background,contentColor=contentColorFor(MaterialTheme.colors.background),elevation = 10.dp){BottomNavigationItem(icon = { Icon(imageVector = Icons.Default.Home,"") },label = { Text(text = "首页")},selected =(selectedIndex.value == 0) ,unselectedContentColor = Color.Gray,selectedContentColor = Color.Red,onClick = { selectedIndex.value = 0 })BottomNavigationItem(icon={Icon(imageVector = Icons.Default.Favorite,"")},label = {Text(text="热门")},selected = (selectedIndex.value== 1),unselectedContentColor =Color.Gray,selectedContentColor = Color.Red,onClick ={selectedIndex.value=1})BottomNavigationItem(icon = { Icon(imageVector = Icons.Default.ShoppingCart,"") },label = { Text(text = "购物车")},selected =(selectedIndex.value == 2) ,unselectedContentColor = Color.Gray,selectedContentColor = Color.Red,onClick = { selectedIndex.value = 2 })BottomNavigationItem(icon={Icon(imageVector = Icons.Default.Person,"")},label = {Text(text="我的")},selected = (selectedIndex.value== 3),unselectedContentColor =Color.Gray,selectedContentColor = Color.Red,onClick ={selectedIndex.value=3})}
}@Composable
fun OrderNowTopBar() {TopAppBar(title = {Text(text = stringResource(id = R.string.app_name),textAlign = TextAlign.Center,modifier = Modifier.fillMaxWidth())},backgroundColor = MaterialTheme.colors.background,contentColor = contentColorFor(MaterialTheme.colors.background))
}@HiltAndroidApp
class OrderNowApplication : Application() {
}
相关文章:

为Android构建现代应用——主体结构
创建Screents和ViewModels 在前面的章节中,我们已经分析了OrderNow项目的理论概念和我们将赋予的组织。 在本章中,我们将开始实现初始结构和模板,这将联接每一个应用程序的部分。 首先将添加以下带有各自视图模型的主屏幕: •…...

【shell脚本】shell脚本之日志切割(进阶实战三)
恭喜你,找到宝藏博主了,这里会分享shell的学习整过程。 shell 对于运维来说是必备技能之一,它可以提高很多运维重复工作,提高效率。 shell的专栏,我会详细地讲解shell的基础和使用,以及一些比较常用的she…...

VMLogin和虚拟机里的浏览器有什么区别?
虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。 指纹浏览器,也称防关联浏览器。 简单来说,就是允许在同一台电设备上操作和管理多个平台、多个账号,账…...

unimrcp server的session资源分配与回收
unimrcp使用APR的内存池管理内存,因此,处理函数中一般都会传递一个pool指针,需要内存时,就从pool里分配一块,一般也不需要关心内存的释放。因为,一路呼叫关联一个session,一个session对应一个po…...
【图论】三种中心性 —— 特征向量、katz 和 PageRank
维基百科:在图论和网络分析中,中心性指标为图中相应网络位置的节点分配排名或数值。中心性这一概念最初起源于社交网络分析,因此很多衡量中心性的术语也反映了其社会学背景。 不同中心性指标对 “重要” 的衡量方式不同,因此适用于…...

[sqoop]将hive查询后的数据导入到MySQL
一、知识点 export:将Hive的表导入到mysql叫导出 搜了很多,发现sqoop在hive导出到mysql时 1)不支持where参数对数据进行过滤。 2)不支持指定hive表的方式导出,只能指定Hive目录进行导出。 二、操作 1、在MySQL中建表 creat…...

Linux df、du命令
df:查看文件系统硬盘使用情况 df 命令,用于显示 Linux 系统中各文件系统的硬盘使用情况,包括文件系统所在硬盘分区的总容量、已使用的容量、剩余容量等。 df 命令的基本格式为: [rootlocalhost ~]# df [选项] [目录或文件名] df…...

java版+免费商城搭建+小程序商城免费搭建+Spring Cloud + Spring Boot + MybatisPlus + 前后端分离 + 二次开发
J2EE企业分布式微服务云快速开发架构 Spring CloudSpring Boot2MybatisOauth2ElementUI 前后端分离 1. 鸿鹄Cloud架构清单 2. Commonservice(通用服务) 通用服务:对spring Cloud组件的使用&封装,是一套完整的针对于分布式微…...

软件设计师学习第一章
计算机组成与体系结构(6分) 内容概述 数据的表示 进制转换 R 进制转十进制使用按权展开法,其具体操作方式为:将 R 进制数的每一位数值用 Rk 形示,即幂的底数是 R ,指数为 k , k 与该位和小数点…...

蓝桥杯单片机第十一届国赛 真题+代码
iic.c /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。 */ #include <STC1…...

IDC报告背后:大模型时代,重新理解AI公有云
大模型之于AI公有云的意义,在于大模型可以改变过去“手工作坊定制算法”的高成本模式,转向“工厂模式”,只需要微调和精调,就可以形成针对性的场景算法。 作者|葛覃 出品|产业家 一年前,依然有不少云计算从业者思…...

UNH-IOL Reservation 一致性测试用例【7】- 清除Reservation
Reservation 系列导航 UNH-IOL Reservation 一致性测试用例【1】- Reservation Report 命令验证 UNH-IOL Reservation 一致性测试用例【2】- Reservation注册 UNH-IOL Reservation 一致性测试用例【3】- 取消注册 UNH-IOL Reservation 一致性测试用例【4】- Reservation Acqui…...

Python 生成随机图片验证码
使用Python生成图片验证码 Python 生成随机图片验证码安装pillow包pillow包生成图片基本用法生成图片验证码 Python 生成随机图片验证码 在写一个Web项目的时候一般要写登录操作,而为了安全起见,现在的登录功能都会加上输入图片验证码这一功能ÿ…...

一些有趣的 js 功能函数
一些有趣的 js 功能函数 数组生成数组打乱数组数组简单数据去重数组唯一值数据去重多数组取交集查找最大值索引查找最小值索引找到最接近的数值压缩多个数组(拉链函数)矩阵交换行和列 数字转换进制转换 正则手机号格式化去除多余空格 web重新加载当前页面…...

摄像头m2dock(MAIX-II DOCK)
官方文档地址 https://wiki.sipeed.com/soft/maixpy3/zh/index.html 一、软件准备 1 烧录镜像软件 2 镜像 当前最近版本镜像文件 3 SDFormatter 4 Maixpy IDE 二、SD卡准备 1 格式化SD卡(用SDFormatter) 2 烧录 3 弹出,插入开发板中 出现…...

SpringBoot 如何优雅的进行全局异常处理
在SpringBoot的开发中,为了提高程序运行的鲁棒性,我们经常需要对各种程序异常进行处理,但是如果在每个出异常的地方进行单独处理的话,这会引入大量业务不相关的异常处理代码,增加了程序的耦合,同时未来想改…...

OSPF路由协议(红茶三杯CCNA)
链路状态路由协议 OSPF(开放式最短路径优先)Open Shortest Path First 是一种链路状态路由协议,无路由循环(全局拓扑),RFC2328 “开放”意味着非私有的 管理型距离:110 OSPF采用SPF算法计算到达…...

redis中使用bloomfilter判断元素是否存在
一 bloomfiler的作用 1.1 bloomfilter的作用 由一个初始值为0的bit数组组成,和多个hash函数构成,用来判断集合中是否存在某个元素。 一个很长的二进制数组(00000000)一系列随机hash算法映射函数。主要用于判断一个元素是否存在…...

互联网医院系统源码实现:打造现代化医疗服务平台
摘要 本文将介绍一个基于Python的简化版互联网医院系统的源码实现,主要包含用户注册与登录、医生信息管理、在线预约挂号、在线问诊与咨询、电子病历管理、在线支付与结算等功能。该源码实现仅为示例,实际开发中需要考虑更多的业务逻辑和安全性。 1. …...

每天100w次登陆请求, 8G 内存该如何设置JVM参数?
一、新系统上线如何规划容量? 1.套路总结 任何新的业务系统在上线以前都需要去估算服务器配置和JVM的内存参数,这个容量与资源规划并不仅仅是系统架构师的随意估算的,需要根据系统所在业务场景去估算,推断出来一个系统运行模型&…...

Fiddler Everywhere(TTP调试抓包工具) for Mac苹果电脑版
Fiddler Everywhere for Mac版是Mac电脑上的一款跨平台的HTTP调试抓包工具,Fiddler Everywhere for Mac能够记录客户端与服务器之间的所有HTTP(S)通信,支持对包进行监视、分析、设置断点、甚至修改请求/响应数据等操作。 适用于任…...

Paragon NTFS2023最新版Mac读写NTFS磁盘工具
Paragon NTFS for Mac是Mac平台上一款非常优秀的读写工具,可以在Mac OS X中完全读写、修改、访问NTFS硬盘、U盘等外接设备的文件。这款软件最大的亮点简书可以让我们读写 NTFS 分区,因为在Mac OS X 系统上,默认状态下我们只能读取NTFS 分区&a…...

vs2013 32位 编译的 dll,重新用vs2022 64位编译,所遇问题记录
目录 一、vs2013 32 DLL 转 VS2022 64 DLL 所遇问题 1、 LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1800”不匹配值“1900” 2、原先VS2013 现在 VS2022 导致的vsnprintf 重定义问题 3、 无法解析的外部符号 __vsnwprintf_s 4、无法解析的外部符号__imp__CertFreeC…...

Linux_CentOS_7.9部署Docker以及镜像加速配置等实操验证全过程手册
前言:实操之前大家应该熟悉一个新的名词DevOps 俗称开发即运维、新一代开发工程师(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障&…...

强引用和弱引用
什么是弱引用和强引用 强引用: JavaScript 中强引用:对象的引用在 JavaScript 中是强引用,也就是将一个引用对象通过变量或常量保存时,那么这个变量或常量就是强引用,这个对象就不会被回收。 弱引用: JavaS…...

tp6 实现excel 导入功能
在项目根目录安装 composer require phpoffice/phpspreadsheet 我们看一下郊果图,如下 点击导入excel表格数据 出现弹窗选择文件,控制台打开输出文档内容 前端layui代码 <form id"uploadForm" class"form-horizontal" encty…...

【C++】类和对象(中篇)
类和对象 类的六大默认成员函数一、构造函数1. 构造函数的概念2. 构造函数的特性 二、析构函数1. 析构函数的概念2. 析构函数的特性 三、拷贝构造函数1. 拷贝构造函数的概念2. 拷贝构造函数的特征 四、赋值运算符重载1. 运算符重载2. 赋值运算符重载 五、取地址及 const 取地址…...

大数据处理架构详解:Lambda架构、Kappa架构、流批一体、Dataflow模型、实时数仓
前言 本文隶属于专栏《大数据理论体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据理论体系 姊妹篇 《分布式数据模型详解:OldSQL &…...

双指针解决n数之和问题
1. 两数之和 1. 两数之和 将时间复杂度降到O(n); class Solution {// 双指针public int[] twoSum(int[] nums, int target) {int nnums.length;int l0;while(l<n){int rn-1;// 找到第一个可能nums[l]nums[r]target的位置while(r>l){if(nums[l]nums[r]targe…...

安全学习DAY07_其他协议抓包技术
协议抓包技术-全局-APP&小程序&PC应用 抓包工具-Wireshark&科来分析&封包 TCPDump: 是可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用…...