声明 Typography 对象,然后给 Text 添加 style 属性,来控制文字的样式。

@Preview(showBackground = true)
@Composable
fun VerticalText() {
val typography = MaterialTheme.typography
Column(
modifier = Modifier.padding(16.dp)
) {
Image(
painter = painterResource(id = R.drawable.hello_world_new_black),
contentDescription = null,
modifier = Modifier
.width(126.dp)
.height(62.dp)
.clip(shape = RoundedCornerShape(4.dp)),
contentScale = ContentScale.Inside
)

Spacer(modifier = Modifier.height(16.dp))

Text(“Hello World!”, style = typography.h3)
Text(“Hello Again World!”, style = typography.body1)
Text(“How old are you, World!”, style = typography.body2)
}
}

Typography 提供如下预设属性,囊括标题、子标题、段落体、按钮等。

最终效果如下:

怎么样,是不是主次开始变得分明了?结构变得清晰了?情节展开得顺滑了?故事开始自然了?……

当然,其他的诸如最大行数、字体、对齐方式等都可以被配置。

二、主题

基本布局已经差不多啦,那么我们再来搞一些共性的东西,就像我们黄种人都有一样的肤色——散在土地里的黄,有种顽强,非常东方……

以前的 View 系统其实也有关于 theme 的定义,那些被定义的 style,在官方定义的一系列 theme 的基础上加以扩展,形成我们 app 的主题。

Compose 框架提供了 Material Design 的实现,Material Design Theme 自然也被应用到 Compose 中,Material Design Theme 包括了对颜色、文本样式和形状等属性的定义,咱们自定义这些属性后,包括 button、cards、switches 等控件都会相应的改变它们的默认样式。

1.颜色

颜色在前端开发中真的是无处不在了,Color 可以帮助我们快速地构建颜色模型。

你可以泡着吃:

val red = Color(0xffff0000)

可以扭着吃:

val blue = Color(red = 0f, green = 0f, blue = 1f)

欸,你还可以干吃:

val black = Color.Black

只要你喜欢,你甚至可以空翻360度加转体一周半的时候吃:

// 我不会空翻,也不会转体,期待你的表现,加油!

Compose 提供了 Colors数来创建成套的浅色或深色:

val Purple200 = Color(0xFFBB86FC)
val Purple500 = Color(0xFF6200EE)
val Purple700 = Color(0xFF3700B3)
val Teal200 = Color(0xFF03DAC5)

private val DarkColorPalette = darkColors(
primary = Pur
ple200,
primaryVariant = Purple700,
secondary = Teal200,
onPrimary = Color.Green
)

private val LightColorPalette = lightColors(
primary = Purple500,
primaryVariant Customize= Purple700,
secondary = Teal200,
onPrimary = Color.Green

/* Other default colors to override
background = Color.White,
surface = Color.White,
onPrimary = Color.White,
onSecondary = Color.Black,
onBackground = Color.Black,
onSurface = Color.Black,
*/
)

然后,就可以传递给 MaterialTheme 使用喽:

@Composable
fun TestComposeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}

MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}

怎么样,还自动适配深色模式。

而且,我们也可以随时随地获取到主题色:

Text(
text = “Hello theming”,
color = MaterialTheme.colors.primary
)

表面颜色和内容颜色又是另一个概念了,许多组件都接受一对颜色和「内容颜色」:

Surface(
color: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(color),

TopAppBar(
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),

这样一来,您不仅可以设置可组合项的颜色,而且还能为包含在可组合项中的内容提供默认颜色。默认情况下,许多可组合项都使用这种内容颜色。例如,Text 的颜色基于其父项的内容颜色,而 Icon :「俺也一样」,它可以使用该颜色来设置其色调。

contentColorFor() 方法可以为任何主题颜色检索适当的“on”颜色。例如,如果您设置 primary 背景,就会将 onPrimary 设置内容颜色。如果您设置非主题背景颜色,还应指定合理的内容颜色。使用 LocalContentColor 可检索与当前背景形成对比的当前内容颜色。

我们以上面自定义的 Theme 来试验,使用它作为我们的主题:

@Preview
@Composable
fun TestColor() {
TestComposeTheme {
Button(onClick = {}) {
Text(
“hello world”
)
}
}
}Customize

效果:

2.字体排版

字体排版主要通过 TypographyTextStyle 类来完成。Typography 构造函数可以提供每种样式的默认值,因此您可以省略不希望自定义的任何样式:

val Rubik = FontFamily(
Font(R.font.rubik_regular),
Font(R.font.rubik_medium, FontWeight.W500),
Font(R.font.rubik_bold, FontWeight.Bold)
)

val MyTypography = Typography(
h1 = TextStyle(
fontFamily = Rubik,
fontWeight = FontWeight.W300,
fontSize = 96.sp
),
body1 = TextStyle(
fontFamily = Rubik,
fontWeight = FontWeight.W600,
fontSize = 16.sp
)
//
)
MaterialTheme(typography = MyTypography, //)

如果您希望自始至终使用同一字体,请指定 defaultFontFamily 参数,并省略所有 TextStyle 元素的 fontFamily

val typography = Typography(defaultFontFamily = Rubik)
MaterialTheme(typography = typography, //)

使用时,可以从主题检索 TextStyle,如以下示例所示:

Text(
text = “Subtitle2 styled”,
style = MaterialTheme.typography.subtitle2
)

3.形状

Compose 中可以轻松地定义各种形状,比如圆角或者操场跑道形状,在传统 View 系统中实现都比较麻烦。

我们现在修改一下上面的 Button 的形状来看看效果:

val Shapes = Shapes(
small = CutCornerShape(
topStart = 16.dp,
topEnd = 0.dp,
bottomStart = 16.dp,
bottomEnd = 0.dp
),
medium = RoundedCornerShape(percent = 50),
large = RoundedCornerShape(0.dp)
)

这里有一点需要注意的是,默认情况下,许多组件使用这些形状。例如,Button、TextField 和 FloatingActionButton 默认为 small,AlertDialog 默认为 medium,而 ModalDrawerLayout 默认为 large。如需查看完整的对应关系,请参阅形状方案参考文档。

三、列表

列表也是个常见的家伙,Android View 系统中早期的 ListView 和后来的 RecyclerView, Flutter 里的 ListView 等。

一个列表就是许多个元素排排站,整齐笔直。那一个纵向(或横向)的布局中动态地添加进许多的元素不就好了。

@Composable
fun MessageList(messages: List) {
Column {
messages.forEach { message ->
MessageRow(message)
}
}
}

来,你猜,RecyclerView 是不是这么写的。这里有个最大的问题,假如你是个交际花,好友从这里排到法国,列表多到滑一晚上滑不到头,那么一次加载是不是要耗费巨大的资源,搞不好卡死了王思聪联系不上你那就太不给面了,不好。

RecyclerView 最大的一个优点是它可以懒加载列表项,一次只加载一个屏幕的条目(四舍五入就是我对)。Compose 中可没有 RecyclerView,但是同样有针对这一问题优化的组件,LazyColumnLazyRow 是垂直和水平方向的懒加载列表控件。我们先来看一下效果:

@Preview
@Composable
fun TestList() {
LazyColumn(modifier = Modifier.fillMaxWidth(),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)) {
// Add a single item
item {
Text(text = “First item”)
}

// Add 5 items
items(10000) { index ->
Text(text = “Item: $index”)
}

// Add another single item
item {
Text(text = “Last item”)
}
}
}

这里加载了一万个元素的列表,看看这丝滑的效果吧(建议就着德芙食用)。

我们还可以像上面一样,通过 contentPadding 设置内容边距,verticalArrangement 则是可以设置 item 间间距,以及均匀地排列元素以充满父空间。

比较遗憾地是 LazyColumnLazyRow 暂时无法设置例如添加元素时地动画,期待后续的加入吧。

LazyColumn 可以轻松地实现粘性标题,只需使用 stickyHeader() 函数即可:

// TODO: This ideally would be done in the ViewModel
val grouped = contacts.groupBy { it.firstName[0] }

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ContactsList(grouped: Map<Char, List>) {
LazyColumn {
grouped.forEach { (initial, contactsForInitial) ->
stickyHeader {
CharacterHeader(initial)
}

items(contactsForInitial) { contact ->
ContactListItem(contact)
}
}
}
}

上面的代码演示了如何通过 Map 数据结构实现粘性标题的数据展示。

既然有列表,那么肯定会有宫格列表,LazyVerticalGrid 则能够帮助我们实现需求。更多用法查看相关 API(没错,我就是 LazyBoy,但我的尊严决定了我不会滚)。

在实际项目开发中,我们经常会遇到将数据分页展示的情况,以减少数据请求压力。借助 Paging 3.0 库 可以来进行分页,Paging 库是 Jetpack 中重要的一项新特性,可帮助您一次加载和显示多个小的数据块。按需载入部分数据会减少网络带宽和系统资源的使用量。

如需显示分页内容列表,可以使用 collectAsLazyPagingItems() 扩展函数,然后将返回的 LazyPagingItems 传入 LazyColumn 中的 items()。与视图中的 Paging 支持类似,您可以通过检查 item 是否为 null,在加载数据时显示占位符:

import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.items
@Composable
fun MessageList(pager: Pager<Int, Message>) {
val lazyPagingItems = pager.flow.collectAsLazyPagingItems()
LazyColumn {
items(lazyPagingItems) { message ->
if (message != null) {
MessageRow(message)
} else {
MessagePlaceholder()
}
}
t androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.items
@Composable
fun MessageList(pager: Pager<Int, Message>) {
val lazyPagingItems = pager.flow.collectAsLazyPagingItems()
LazyColumn {
items(lazyPagingItems) { message ->
if (message != null) {
MessageRow(message)
} else {
MessagePlaceholder()
}
}

Jetpack Compose 初体验(上),retrofit原理面试相关推荐

  1. Jetpack Compose 初体验(上),flutter人脸识别系统

    fun VerticalText() { Column( modifier = Modifier.padding(16.dp) ) { Text("Hello World!") T ...

  2. Jetpack Compose 初体验(上)

    Image 的其中一个构造函数支持以下参数,其中 painter 参数和 contentDescription 参数没有默认值,为必传参数. 这样,图片就被构造出来啦,看一下效果: 那怎么该对图片进行 ...

  3. retrofit原理面试,2021最新百度、头条等公司Android社招面试题目,含答案解析

    基本情况 硕士生,Android开发岗 此文主要是2021年初春招实习的面试和正式校招面试经验汇总,最终校招拿到了腾讯,百度,美团,网易等offer 主要包括阿里4面,腾讯8面,字节3面,百度3面,美 ...

  4. 麒麟座V3.1接入OneNET平台初体验--上传温湿度

    一..前言 这篇文章不得不有前言, 一直在搭建自己的云服务器, 最后还是觉得OneNet的平台更加方便, 省时省力, 功能强大, 调用方便. 这次开发麒麟座也没有硬件基础, 用着官方的例程就成功连接到 ...

  5. jetpack compose原理解析

    目录 jetpack compose原理解析 jetpack compse 声明式ui开发 原理分析 整体框架介绍 compose LayoutNode布局介绍 @Composeable注解实现细节 ...

  6. 探索 Jetpack Compose

    前言 在大前端概念快速发展下,出现了很多声明式 UI 写法的语言或框架,像前端的 react.iOS 的 Swift UI,还有 Google 的 Flutter,但很少会听到 Android 原生有 ...

  7. IBatis初体验2

    继上一篇IBatis初体验 上一篇介绍了基本配置和一个简单的插入(其它RUD操作也类似) 本篇主要是对于一对多和多对一的基本使用 还是Userinfo 与 Score  双向一对多关系 javaBea ...

  8. 面试杭州安恒的初体验

    一.题记 大三快结束前,跟着毕设老师推荐,去面试杭州安恒这家安全厂商公司,面试前做的准备很少,也是我第一次面试的初体验-感慨颇丰.想谈谈自己和今后发展. 二.技术面试 开始聊了几个比较熟知的漏洞,比如 ...

  9. Rasa课程、Rasa培训、Rasa面试系列之:Rasa 3.x部署安装初体验

    Rasa课程.Rasa培训.Rasa面试系列之:Rasa 3.x部署安装初体验 Rasa 3.x部署安装 进入Ananconda系统,新建rasa虚拟环境 conda create --name in ...

最新文章

  1. java opencv 环境_基于java的OpenCV环境搭建
  2. r语言 调用 c,R语言数据的输入和输出操作
  3. 802.11b协议的一些介绍和说明
  4. 第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页...
  5. 晒一下MAC下终端颜色配置
  6. UVA - 514 Rails-栈
  7. java世博会,反应原生失去的世博会
  8. liblfds 测试
  9. Spring | SpringMVC
  10. H3C CLI基础笔记(交换机,链路聚合-DHCP)
  11. 菊安酱的机器学习实战
  12. 【C语言】斐波那契数列
  13. 【角度刁钻】如果把线程当作一个人来对待,秒懂
  14. WIN10系统重新安装与初始化教程
  15. 如何用python裁剪图片
  16. MATLAB彩色图像处理
  17. android mp4 画面裁剪,说说Android的视频裁剪(三)
  18. (Java)密码学课程设计(WinRAR解密 + 基于shamir门限秘密分割的图像秘密共享和安全存储系统)
  19. 导出服务器dmp文件,编辑dmp文件解决导入导出问题
  20. html+css实现必要等商城页面

热门文章

  1. 在前端中清除IE浏览器缓存问题
  2. 超算平台安装DL_POLY分子动力学软件
  3. 区块链未来的发展前景是什么?
  4. 美国J1签证面签需要准备哪些材料?
  5. 实例恢复(Instance Recovery)之前滚(Rolling Forward)和回滚(Rolling Back)
  6. 往事如烟 - 老钟8
  7. 淘宝经典移动轮播制作
  8. linux与window文件通过串口传输方法(zmod传输方法)
  9. 湿空气性质计算,随笔与学习记录 (5.空气比焓)
  10. QVector使用示例