Compose Weekly #1: 小狗领养应用

本文同步发表于我的微信公众号,在微信搜索 OpenCV or Android 即可关注。

前言

最近Android官方发起了Jetpack Compose的推广活动:Jetpack Compose开发者挑战赛。活动时间一个月,每周一题,广大开发者根据官方需求,Clone官方模板工程并使用Jetpack Compose技术结题后按要求提交,即可参与活动。上周完成了第一题,今天第二周的题目已经出来了,感兴趣的同学可以参与下。

环境

学习任何技术,首先拜读官文,无一例外。

第一周

题目:小狗领养应用

要求:包含显示小狗列表的概览画面,以及显示每只小狗具体情况的详细信息画面。

知识点:

  • 基础控件:Column、Modifier、Card、Box、Text、Icon、Image、IconButton、Spacer等
  • 控件修饰:Modifier
  • 可变状态:mutableStateOf

定义数据

1// 狗狗实体 2data class Dog(val name: String, val avatar: Int, val desc: String) 3 4// 狗狗列表 5object DogPool { 6 val Dogs = listOf( 7 Dog(getRandomString(6), getRandomAvatar(), getRandomString(100)), 8 Dog(getRandomString(6), getRandomAvatar(), getRandomString(100)), 9 Dog(getRandomString(6), getRandomAvatar(), getRandomString(100)), 10 Dog(getRandomString(6), getRandomAvatar(), getRandomString(100)), 11 Dog(getRandomString(6), getRandomAvatar(), getRandomString(100)), 12 Dog(getRandomString(6), getRandomAvatar(), getRandomString(100)), 13 ) 14} 15 16// 狗狗头像素材 17val avatars = listOf( 18 R.drawable.dog_one, 19 R.drawable.dog_two, 20 R.drawable.dog_three, 21 R.drawable.dog_four, 22 R.drawable.dog_five, 23 R.drawable.dog_six 24) 25 26// 随机产生狗狗头像 27fun getRandomAvatar(): Int { 28 return avatars[Random.nextInt(0, 5)] 29} 30 31// 随机生成固定长度字符串 32fun getRandomString(length: Int): String { 33 val allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz" 34 return (1..length) 35 .map { allowedChars.random() } 36 .joinToString("") 37}

列表界面

使用Column展示一个纵向列表,使用Modifier调整布局元素的各种属性。

1Column(modifier = Modifier.verticalScroll(rememberScrollState())) { 2 Spacer(modifier = Modifier.size(16.dp)) 3 DogPool.Dogs.forEach { 4 Box(Modifier.padding(8.dp)) { 5 DogView( 6 dog = it, 7 modifier = Modifier 8 .fillMaxWidth() 9 .clickable { selectedDog = it } 10 ) 11 } 12 } 13}

列表项

1@Composable 2fun DogView(dog: Dog, modifier: Modifier = Modifier) { 3 Card(modifier, shape = RoundedCornerShape(26.dp)) { 4 Box { 5 Image( 6 painterResource(dog.avatar), 7 null, 8 modifier = Modifier.fillMaxWidth(), 9 contentScale = ContentScale.FillWidth 10 ) 11 Box( 12 modifier = Modifier 13 .align(Alignment.BottomStart) 14 .background( 15 Brush.verticalGradient( 16 listOf( 17 Color.Transparent, 18 MaterialTheme.colors.onSurface 19 ) 20 ) 21 ) 22 .fillMaxWidth() 23 .padding(26.dp) 24 ) { 25 Text( 26 text = dog.name, 27 style = MaterialTheme.typography.h5, 28 color = MaterialTheme.colors.surface 29 ) 30 } 31 } 32 } 33}

详情界面

1@Composable 2fun DogDetails(dog: Dog) { 3 val context = LocalContext.current as? Activity 4 val scrollState = rememberScrollState() 5 6 // Calculate the offset of the background image to make it scroll with a parallax effect 7 val imageOffset = (-scrollState.value * 0.2f).dp 8 9 // Calculate the alpha used in the background of the back arrow 10 val iconBackgroundAlpha = 11 ((scrollState.value / START_TOP_PADDING.toFloat()) * 0.2f).coerceAtMost(0.2f) 12 13 Box { 14 Image( 15 painter = painterResource(id = dog.avatar), 16 contentDescription = null, 17 contentScale = ContentScale.FillWidth, 18 modifier = Modifier 19 .offset(y = imageOffset) 20 .height(200.dp) 21 .fillMaxWidth() 22 ) 23 24 Column( 25 Modifier 26 .verticalScroll(scrollState) 27 .padding(top = START_TOP_PADDING.dp) 28 .background( 29 MaterialTheme.colors.surface, 30 RoundedCornerShape(topStart = 3.dp, topEnd = 20.dp) 31 ) 32 .fillMaxHeight() 33 .fillMaxWidth() 34 .padding(all = 32.dp) 35 ) { 36 Text("Hello I Am", style = MaterialTheme.typography.h6) 37 Spacer(Modifier.size(10.dp)) 38 Text(text = dog.name, style = MaterialTheme.typography.h3) 39 Spacer(Modifier.size(16.dp)) 40 Spacer(modifier = Modifier.size(16.dp)) 41 Text(text = dog.desc) 42 } 43 44 IconButton( 45 onClick = { context?.onBackPressed() }, 46 modifier = Modifier 47 .padding(8.dp) 48 .background(Color.Black.copy(alpha = iconBackgroundAlpha), shape = CircleShape) 49 ) { 50 Icon( 51 painter = painterResource(id = R.drawable.ic_arrow_back), 52 contentDescription = null, 53 modifier = Modifier 54 .size(32.dp), 55 tint = Color.White 56 ) 57 } 58 } 59}

代码检查

./gradlew app:spotlessApply

针对Wildcard import错误,进行如下配置后删除对应以*号形式引入的包,重新执行引入操作。

解决Wildcard import错误

效果

列表界面

详情界面

源码

https://github.com/onlyloveyd/Jetpack-Compose-Dog

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Compose Weekly #2:Countdown Timer

本文同步发表于我的微信公众号,在微信搜索OpenCVorAndroid即可关注。前言最近Android官方发起了JetpackCompose的推广活动:JetpackCompose开发者挑战赛。活动时间一个月,每周一题,广大开发者根据官方需求,Clone官方模板工程并使用JetpackCompose技术结题后按要求提交,即可参与活动。

Compose Weekly #4:Weather App

本文同步发表于我的微信公众号,在微信搜索OpenCVorAndroid即可关注。前言It'sraining...Compose!Pulloutallthestopsforthisfinalchallenge.BuildabeautifulweatherappforachancetowinaPixel