当前位置: 首页 > news >正文

为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 在前面的章节中&#xff0c;我们已经分析了OrderNow项目的理论概念和我们将赋予的组织。 在本章中&#xff0c;我们将开始实现初始结构和模板&#xff0c;这将联接每一个应用程序的部分。 首先将添加以下带有各自视图模型的主屏幕&#xff1a; •…...

【shell脚本】shell脚本之日志切割(进阶实战三)

恭喜你&#xff0c;找到宝藏博主了&#xff0c;这里会分享shell的学习整过程。 shell 对于运维来说是必备技能之一&#xff0c;它可以提高很多运维重复工作&#xff0c;提高效率。 shell的专栏&#xff0c;我会详细地讲解shell的基础和使用&#xff0c;以及一些比较常用的she…...

VMLogin和虚拟机里的浏览器有什么区别?

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

unimrcp server的session资源分配与回收

unimrcp使用APR的内存池管理内存&#xff0c;因此&#xff0c;处理函数中一般都会传递一个pool指针&#xff0c;需要内存时&#xff0c;就从pool里分配一块&#xff0c;一般也不需要关心内存的释放。因为&#xff0c;一路呼叫关联一个session&#xff0c;一个session对应一个po…...

【图论】三种中心性 —— 特征向量、katz 和 PageRank

维基百科&#xff1a;在图论和网络分析中&#xff0c;中心性指标为图中相应网络位置的节点分配排名或数值。中心性这一概念最初起源于社交网络分析&#xff0c;因此很多衡量中心性的术语也反映了其社会学背景。 不同中心性指标对 “重要” 的衡量方式不同&#xff0c;因此适用于…...

[sqoop]将hive查询后的数据导入到MySQL

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

Linux df、du命令

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

java版+免费商城搭建+小程序商城免费搭建+Spring Cloud + Spring Boot + MybatisPlus + 前后端分离 + 二次开发

J2EE企业分布式微服务云快速开发架构 Spring CloudSpring Boot2MybatisOauth2ElementUI 前后端分离 1. 鸿鹄Cloud架构清单 2. Commonservice&#xff08;通用服务&#xff09; 通用服务&#xff1a;对spring Cloud组件的使用&封装&#xff0c;是一套完整的针对于分布式微…...

软件设计师学习第一章

计算机组成与体系结构&#xff08;6分&#xff09; 内容概述 数据的表示 进制转换 R 进制转十进制使用按权展开法&#xff0c;其具体操作方式为&#xff1a;将 R 进制数的每一位数值用 Rk 形示&#xff0c;即幂的底数是 R &#xff0c;指数为 k &#xff0c; k 与该位和小数点…...

蓝桥杯单片机第十一届国赛 真题+代码

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

IDC报告背后:大模型时代,重新理解AI公有云

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

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项目的时候一般要写登录操作&#xff0c;而为了安全起见&#xff0c;现在的登录功能都会加上输入图片验证码这一功能&#xff…...

一些有趣的 js 功能函数

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

摄像头m2dock(MAIX-II DOCK)

官方文档地址 https://wiki.sipeed.com/soft/maixpy3/zh/index.html 一、软件准备 1 烧录镜像软件 2 镜像 当前最近版本镜像文件 3 SDFormatter 4 Maixpy IDE 二、SD卡准备 1 格式化SD卡&#xff08;用SDFormatter&#xff09; 2 烧录 3 弹出&#xff0c;插入开发板中 出现…...

SpringBoot 如何优雅的进行全局异常处理

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

OSPF路由协议(红茶三杯CCNA)

链路状态路由协议 OSPF&#xff08;开放式最短路径优先&#xff09;Open Shortest Path First 是一种链路状态路由协议&#xff0c;无路由循环&#xff08;全局拓扑&#xff09;&#xff0c;RFC2328 “开放”意味着非私有的 管理型距离&#xff1a;110 OSPF采用SPF算法计算到达…...

redis中使用bloomfilter判断元素是否存在

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

互联网医院系统源码实现:打造现代化医疗服务平台

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

每天100w次登陆请求, 8G 内存该如何设置JVM参数?

一、新系统上线如何规划容量&#xff1f; 1.套路总结 任何新的业务系统在上线以前都需要去估算服务器配置和JVM的内存参数&#xff0c;这个容量与资源规划并不仅仅是系统架构师的随意估算的&#xff0c;需要根据系统所在业务场景去估算&#xff0c;推断出来一个系统运行模型&…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...