Android Compose Bloom 项目实战 (四) : 主页

news2024/11/15 4:58:28

1. 前言

上篇文章 我们实现了 Compose Bloom项目的开发页,这篇文章接着上文,来介绍主页的开发。

在这里插入图片描述

2. 分析页面布局

根据UI稿我们可知,这个页面有一个底部切换的BottomBar,还有一个搜索框,一个横向的列表以及一个竖向的列表。
在这里插入图片描述

3. 定义数据

首先先定义数据

data class ImageItem(val name: String, val resId: Int)

val navList = listOf(
    ImageItem("Home", R.drawable.ic_home),
    ImageItem("Favorites", R.drawable.ic_favorite_border),
    ImageItem("Profile", R.drawable.ic_account_circle),
    ImageItem("Cart", R.drawable.ic_shopping_cart)
)
val gardenList = listOf(
    ImageItem("Monstera", R.drawable.monstera),
    ImageItem("Aglaonema", R.drawable.aglaonema),
    ImageItem("Peace lily", R.drawable.peace_lily),
    ImageItem("Fiddle leaf", R.drawable.fiddle_leaf),
    ImageItem("Snake plant", R.drawable.snake_plant),
    ImageItem("Pothos", R.drawable.pothos),
)
val themeList = listOf(
    ImageItem("Desert chic", R.drawable.desert_chic),
    ImageItem("Tiny terrariums", R.drawable.tiny_terrariums),
    ImageItem("Jungle vibes", R.drawable.jungle_vibes),
    ImageItem("Easy care", R.drawable.easy_care),
    ImageItem("Statements", R.drawable.statements),
)

4. 实现底部Tab栏BottomBar

ScaffoldAndroid中的脚手架ScaffoldCompose 提供了大量基于 Material Design 的可组合项以及依赖项,旨在简化界面的构建。Scaffold 可以实现具有基本 Material Design 布局结构的界面,比如DrawerFloatingActionButtonTopAppBar以及BottomBar

@Preview
@Composable
fun HomePage() {
    Scaffold(bottomBar = {
        BottomBar()
    }) {

    }
}

@Preview(showBackground = true, backgroundColor = 0xFFFFFF)
@Composable
fun BottomBar() {
    BottomNavigation(
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp),
        backgroundColor = pink100,
    ) {
        navList.forEach {
            val isSelected = "Home" == it.name
            BottomNavigationItem(selected = isSelected, onClick = { }, icon = {
                Image(
                    painter = painterResource(id = it.resId),
                    contentDescription = "",
                    modifier = Modifier.size(24.dp),
                    colorFilter = ColorFilter.tint(
                        if (isSelected) gray else Color(
                            0xff757575
                        )
                    )
                )
            }, label = {
                Text(
                    text = it.name,
                    style = caption,
                    color = if (isSelected) gray else Color(0xff757575)
                )
            })
        }
    }
}

预览效果如下所示
在这里插入图片描述

5. 实现搜索框

搜索框其实就是OutlinedTextField,带边框的输入框,leadingIcon中传入Icon,用来显示搜索图标。

@Preview(showBackground = true)
@Composable
fun SearchBar() {
    val keyword = remember { mutableStateOf("") }
    Box(
        modifier = Modifier
            .height(96.dp)
            .padding(top = 40.dp)
    ) {
        OutlinedTextField(
            value = keyword.value, onValueChange = {
                keyword.value = it
            }, modifier = Modifier
                .fillMaxWidth()
                .padding(start = 16.dp, end = 16.dp),
            maxLines = 1,
            placeholder = { Text(text = "Search", style = MaterialTheme.typography.body1) },
            leadingIcon = {
                Icon(
                    imageVector = Icons.Outlined.Search,
                    contentDescription = null,
                    modifier = Modifier.size(18.dp)
                )
            }
        )
    }
}

预览效果如下所示
在这里插入图片描述

6. 实现横向列表

首先实现Item

@Composable
private fun BloomRowTitle() {
    Text(
        text = "Browse themes",
        modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 6.dp),
        style = h1
    )
}

然后实现横向列表

@Composable
fun BloomRowList() {
    LazyRow(content = {
        items(themeList.size) {
            ThemeCard(themeList[it])
        }
    }, modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 3.dp))
}

预览效果如下

@Preview(showBackground = true, backgroundColor = 0xFFFFFF)
@Composable
fun BloomRowPreView() {
    Column {
        BloomRowTitle()
        BloomRowList()
    }
}

在这里插入图片描述

7. 实现竖向的列表

首先实现Item

@Composable
fun BloomListTitle() {
    Box(
        modifier = Modifier
            .padding(16.dp)
            .fillMaxWidth(),
    ) {
        Text(
            text = "Design you home garden",
            modifier = Modifier.align(Alignment.CenterStart),
            style = h1,
        )
        Image(
            imageVector = Icons.Default.FilterList,
            contentDescription = null,
            modifier = Modifier.align(Alignment.CenterEnd),
            colorFilter = ColorFilter.tint(MaterialTheme.colors.onBackground)
        )
    }
}

然后实现竖向列表

@Composable
fun BloomList() {
    LazyColumn(content = {
        items(gardenList.size) {
            ItemGarden(it == 0, gardenList[it])
        }
    })
}

来实现具体的Item

@Composable
fun ItemGarden(checked: Boolean, item: ImageItem) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp, horizontal = 16.dp)
            .height(64.dp),
    ) {
        Image(
            painter = painterResource(id = item.resId),
            contentDescription = "",
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .height(64.dp)
                .width(64.dp)
                .clip(shape = RoundedCornerShape(4.dp))
        )
        Column(modifier = Modifier.padding(start = 80.dp)) {
            Text(text = item.name, style = h2, modifier = Modifier.padding(top = 12.dp))
            Text(text = "This is a description", style = body1)
        }
        Checkbox(
            checked = checked,
            onCheckedChange = {},
            modifier = Modifier
                .align(Alignment.CenterEnd)
                .padding(end = 16.dp)
        )
        Divider(
            modifier = Modifier
                .padding(start = 72.dp, end = 16.dp)
                .align(Alignment.BottomStart)
        )
    }
}

预览效果如下
在这里插入图片描述

8. 组装所有组件

@Composable
fun HomePage() {
    Scaffold(bottomBar = {
        BottomBar()
    }) {
        Column {
            SearchBar()
            BloomRowTitle()
            BloomRowList()
            BloomListTitle()
            BloomList()
        }
    }
}

最终显示效果如下

在这里插入图片描述

9. 小结

至此,我们就完成了主页的UI效果,下一篇文章,我们将来处理Compose页面见的跳转 (待更新)

Compose 项目实战 系列文章
Android Compose Bloom 项目实战 (一) : 项目说明与配置
Android Compose Bloom 项目实战 (二) : 欢迎页
Android Compose Bloom 项目实战 (三) : 登录页

本文源码 : ComposeBloom

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/356768.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RNN GRU模型 LSTM模型图解笔记

RNN模型图解引用RNN模型GRULSTM深度RNN双向循环神经网络引用 动手学深度学习v2–李沐 LSTM长短期记忆网络3D模型–B站up梗直哥丶 RNN模型 加入了一个隐变量(状态),隐变量由上个隐变量和上一个输入而更新,这样模型就可以达到具有短期记忆的效…

加油站会员管理小程序实战开发教程10

上一篇我们介绍了计算距离及到店导航的功能,本篇我们介绍一下今日油价的功能。 如果要按日显示最新的数据,那么我们首先需要有数据源来存放每日的油价数据。这里涉及数据源的时候要考虑你的数据是只录入一条,还是每日录入一条。 录入一条呢,比较简单,但有个问题是如果我…

制作for arm64 cpu架构的docker镜像

我前段时间买了个阿里云,没有留意CPU的架构是ARM的,结果部署系统的时候就发现出问题了,部署在docker里的容器实例根本跑不起来,提示什么执行文件格式错误(“exec format error”)。 究其原因,…

spring注解方式整合Dubbo源码解析

系列文章目录 前言 本节我们的Dubbo源码版本基于2.6.x 在前一章我们的整合案例中,我们有几个比较关键的步骤: 在启动类上标注了EnableDubbo注解在provider类上面标注了Service注解来提供dubbo服务在消费的时候通过Reference注解引入dubbo服务在配置文件…

软考中级-面向对象

面向对象基础(1)类类分为三种:实体类(世间万物)、接口类(又称边界类,提供用户与系统交互的方式)、控制类(前两类之间的媒介)。对象:由对象名数据&…

【jumpServer 功能梳理】

用户管理 1.1 用户列表 创建jumpServe 账号 ;角色分为用户 管理员;更新账号信息;查看用户详情以及授权的资产; 1.2 用户组 用户组,这个组的意义在于用一个统称对接资源;用户组包含多个用户,可以操作增加删除…

LeetCode初级算法题:两数之和+斐波拉契数列多种java解法

目录7 两数之和题目描述:解题思路与代码暴力解法:解法一:二分查找解法二:双指针2 斐波那契数列题目描述:解题思路与代码![请添加图片描述](https://img-blog.csdnimg.cn/d06a95d7989b4794bd7f5f02fbd6f87e.png)解法一&…

spring之使用Spring的AOP

文章目录前言一、准备工作1、添加相应的依赖2、添加相应的命名空间3、创建目标类4、创建切面二、使用AOP1.在切面类中编写增强代码以及切点表达式2、开启aspectj的自动代理3、测试类4、测试结果前言 Spring对AOP的实现包括以下三种方式 1、Spring框架结合AspectJ框架实现的AOP…

自抗扰控制ADRC之反馈控制律(NLSEF)

目录 前言 1.非线性状态误差反馈控制律(NLSEF) 1.1 控制律形式 1.2 控制量的生成(或者说扰动的补偿) 1.2.1补偿形式① 1.2.1补偿形式② 2.仿真分析 2.1仿真模型 2.2仿真结果 前言 前面的两篇博客依次介绍了TD微分跟踪器安排过渡过程、扩张观测器: 自抗扰…

用腾讯云同步Obsidian笔记

介绍 之前用gitee同步OB笔记,同时做图床。但由于git系产品设置起来相对复杂,且后续可能有外链过审等问题。周五被同事小姐姐安利了用腾讯云COS,试了一下,果然不错。其主要优点如下: 设置简单,学习成本低&…

WSL(Windows Subsystem for Linux)

一、WSL优势 •传统方式:获取Linux操作系统环境,必须安装完整的虚拟机,如VMware•WSL:以非常轻量化的方式,得到Linux系统环境总结:WSL更方便,简单、好用、轻量化、省内存 二、什么是WSL ①不…

Go语言基础(十五):垃圾回收机制(三色标记)

文章目录一、标记清除(三色标记)大致原理1、标记细节2、root对象二、垃圾回收触发机制垃圾回收(Garbage Collection),是一种自动管理内存的机制。传统编程语言(如C/C)需要开发者对无用内存资源进…

Android实例仿真之三

目录 四 Android架构探究 五 大骨架仿真 六 Android实例分析思路拓展 四 Android架构探究 首先,Android系统所带来的好处,就在于它本身代码的开放性,这提供了一个学习、借鉴的平台。这对分析仿真而言,本身就是一大利好&#xf…

[JAVA安全]Spring Messaging之CVE-2018-1270

漏洞简介 Spring 框架中通过spring-messaging 模块来实现 STOMP (Simple Text-Orientated Messaging Protocol),STOMP是一种封装 WebSocket的简单消息协议。攻击者可以通过建立WebSocket连接并发送一条消息造成远程代码执行, spring-messagin…

C++笔记 模板的进阶知识

目录 1. 非类型模板参数 2.模板的特化 2.1 函数模板的特化 2.2 类模板的特化 2.2.1 全特化 2.2.2 偏特化 3.模板的分离编译 3.1 什么是分离编译? 3.2 模板的分离编译 4.模板的总结 模板的初阶内容:(594条消息) C模板的原理和使用_全貌的博客-CSD…

【干货】如何打造HR无法拒绝的简历?测试开发大牛带手把手你写简历!

通过率90%,优秀的软件测试简历长什么样? 也许口才好的人会觉得简历不重要,能说就行了,那是因为你没有体会过石沉大海的感觉! 很多人觉得疑惑,为什么我投了那么多简历,都没有接到面试通知&…

加油站会员管理小程序实战开发教程15 完结篇

这篇是本次实战课程的最后一篇,我们在上篇还有两个问题没解决。一个是会员卡类型显示不对,一个是不同的会员卡我们希望背景色显示不同。我们先处理一下这两个问题 1 显示会员卡类型 在列表上直接显示会员卡类型,目前显示的是数字,这个是因为枚举类型导致的。枚举类型在数…

关于vb6无边框的窗体开发遇到的部分问题的解决方案

为了美化或自定义窗体,通常会把窗体做成无边框形式,使用无边框窗体会存在一些问题的,以vb为例,当窗体borderstyle设置为0时,会出现以下问题:1.任务栏不再出现程序图标 2.窗体无法拖行移动 3.窗体无法拖动缩放&#…

WampServer安装教程

文章目录简介:官网地址安装步骤:我是阿波,学习PHP记录一下笔记,如果对你有帮助,欢迎一键三连,谢谢! 简介: WampServer是一个用于Windows操作系统的Web开发环境,其名称来…

10- 天猫用户复购预测 (机器学习集成算法) (项目十) *

项目难点 merchant: 商人重命名列名: user_log.rename(columns{seller_id:merchant_id}, inplaceTrue)数据类型转换: user_log[item_id] user_log[item_id].astype(int32)主要使用方法: xgboost, lightbm竞赛地址: 天猫复购预测之挑战Baseline_学习赛_天池大赛-阿里云天池…