# Compose开发者应战赛二周目
为协作Jetpack Compose beta版的发布,Google官方发起了Compose开发者应战赛活动,现在现已入二周目 android-dev-challengeapplication-2
第二周的标题是运用Compappearanceose完毕倒计时app 。标题出的十分稳妥,难度不高,可是能引导我们有针对性地去学习Compose的某些特性,比方这google个app的完毕canvas标签需appear求我们学习和了解state以及animations的运用。
Note:对Composcanvas动漫e开发者应战赛google地球及其参与方android是什么手机牌子法有喜爱的朋友能够参看:《Jetpack Compose 开发应战赛》
项目中运字体转换器用的都是Compose最基础的API,花时刻不多,但完毕作用还比较满意,可见Compose的确有助于提升UI开发功率,这儿简略与我们分享一下完毕进程。
# App完毕
1. 画面构成
app由两个画面构成:
-
输入画面(InputScreen) :
通google空间过数字软键盘输入时刻,当新输入数字时,悉数数字左appearance移;backspace回退最近一次输入时,悉数数字右移。相似核算器aappleidpp的输入和闪现逻辑。 -
倒计时画Google面(Cogoogle浏览器untdownScreen):
闪android下载软件app现其时剩余时刻并配有动画作用;依据剩余时刻的不同,文字格式和大小会做出改动:最终10秒倒计时的文字也有更夺目的缩放动画。
more than 1h | more than 1m & less than 1h | less than 1m |
---|---|---|
state操控页面跳转
页面之间的跳转逻辑:
- InputScreen完毕输入字体大小怎么调后,点击底部Next,跳转到CountdownScreen进入倒计时
- CountdownScreen点击底部Cancel,回来InputScreen
Compose没有Activitycanvas下载
、Fragment
这样的页面处理单元,所谓的页面只不过是一个全屏的Composable
,一般能够运用state
完毕。凌乱的页面场景能够凭借navigatiocanvas下载n-compose
enum class Screen {
Input, Countdown
}
@Composable
fun MyApp() {
var timeInSecandroid下载 = 0
Surface(color = MaterialTheme.colors.background) {
var s字体规划creen by remember { mutableStateOf(Screen.Input) }
Crossfade(targetState = screen) {
whenandroid是什么手机牌子 (scapprovereen) {
Screen.Incanvas软件put -> InputScreen {
screen = Screen.CountdownScreen
}
Screen.Countdown -> CountdownScreen(timeInSec) {
screen = Screencanvas动漫.Input
}
}
}
}
}
-
screen
: 运字体管家用state保存并监听其时页面google空间的改动, -
Crossfade
:Crossfade
能够淡入淡出的切换内部布局;内部依据screen切换不同页面。 -
tandroid的drawable类imeInSec
:Inputandroid体系Screen的输入存入timeInSec
,并携带到CountdownScreen
2. 输入画面(InputScreen)
InputgoogleplayScreen包括以下元素:
- 输入作用:input-value
- 回退:backspace
- 软键盘:softkeybappearoard
- 底部:next
依据其字体规划时的输入作用,画面各元素会发生改动。
- 当有输入作用时:next闪现、backspace激活、input-value高亮;
- 反之,next躲藏、backspace禁用、字体全国input-value低appearance亮
state驱动UI改写
假定用传统写法会比较烦琐,需求在影响输入作用的当地设置监听,google浏览器例如本例中需求分别监听baandroid体系ckspace和next。当输入改动时指令式地去批改相关字体大师元素,页面凌乱度会跟着页面元素增字体下载多呈指数级添加。
运用Compose则简略得多,我们只需求canvas渠道将输入作用包装成state
并监听,当state改动时,悉数Composable
从头实施、更新情况。即使元素增多也不会影响已有代码,凌乱度不会android/yunos添加。
var input by remember {
mutableStateOf(listOf<Int>())
}
val hasCountdownValue = remember(input) {
inapplicationput.isNotEmpty()
}
-
mutabl字体美化大师免费下载eStateOf
创立一个可改动的state,经过by
署理进行google地球订阅,当statappearancee改动时其时Composacanvas软件ble会从头实施。 - 因为Composable会重复实施,运canvas交大用
remember{appearance}
能够防止因为Compcanvas渠道osable的实施重复而canvas动漫重复googleplay创立state实例。 - 当android的drawable类
remember
的参数改动时,block会从头实施,上面例子中,当input改动时,判别input是否为空并android下载软件app保存在hasCountdownValuandroid体系e
中,供其他Composable参照。
Column() {
...
Row(
Modifier
.fillMaxWidth()
.height(100.dp字体大小怎么调)
.padding(start = 30.d字体规划p, eandroid的drawable类nd = 30.dp)
) {
//Input-value
listOandroid体系f(hou to "h", min to "m", sec to "s").forEach {
DisplayTime(it.first, itapplication.secondcanvas动漫, hasCountdownValue)
}
//Backgoogle查找引擎进口口space
Imagooglege(
imageVector = Icons.Default.Backspace,
cgoogle谷歌查找主页ontentDescription = null,
colorFilter = ColorFilter.tint(
Color.Unspecified.copy(
//依据hasCountdownValue闪现不同亮度
if (hasCountdownValue) 1.0f else 0.5f
)
)
)
}
..google地球.
//依据hasCountdownValue,是否闪现next
if (hascanvas软件CountdownValue) {
Image(
imageVector = Icons.Default.PlayCirclecanvas下载,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheappleme.colors.primary)
)
}
}canvas中文
如上,声明UI的一起参与hasCountdowncanvas渠道Value
的判别逻辑,然后等候再次改写就OK,无需像传统写法那样设置监听并指令式地更新UI。
3. 倒计时画面(CountdownScreen)
CountdownScreen主要包括以下元素:
- 文字部分:闪现hour、second、minutes 以及ms
- 气氛部分:多个不同类型的圆形动画
- 底部Cancel
运用animation核算倒计时
怎么准确地核算倒计时呢?
开端的方案是运用canvas交大flow
核算倒计时,然APP后将flow转成state,驱动UI改写:
private fun interval(sum: Long, step: Long): Flow<Long> = flow {
while (sum > 0) {
delayandroid下载(step)
sum -= step
emit(sum)
}
}
可是经过字体美化大师查验发现,因为协程切换也有开支,运用delay处理倒计时并不准确。
通APP过考虑决定运用animation处理倒计时
var trigger by remember { mutableStateOf(timeInSec) }
val elapsapp装置下载ed by animateIntAsState(
targetValue = trigger * 1000,
animatandroid/yunosionSpec = tween(timeInSec * 1000, easandroid下载装置ing = LinearEasing)
)
DisposableEffect(Unit) {
trigger = 0
onDispose { }
}
- Compose的动画也是通canvas中文过state驱动的,
animateIntAsState
界说动画、核算动画估值appearance并转成state。 - 动画由
targetValue
的改动触发发动。 -
animationSpec
用来配备动画类型,例如这儿经过tweenandroid下载装置
配备一个线性的补间动画。duration
设置为timeInSec * 1google服务结构000
,也便是倒计不时长的ms。 -
DisposableEappearanceffect
用来在纯函数中实施副作用。假定参数发生改动,block中的逻辑会在每次重绘(Composition)时实施。DisposableEffect(Unit)
因为参googleplay数永久不会改动,意味着block只会在第一次上屏时只实施一次。 -
triggeappleidr
初始情况为字体下载timeInSec(倒计时总时长),然后在第一次上屏时设置为0,targetValue
改动触Canvas发了动画:从timeIappearnSec*1000
实施到android的drawable类0
,duration为timeInSec*1000
,动画完毕appleid时便是倒计时的完毕,而且Android必定准确,没有差错。
接下来只需求将elapsed
换算成合适的文字闪现就OK了
val (hou, min, sec) = remember(elapsed字体 / 1000) {
val elapsedInSec = elapsed / 1000
val hou = elapsedInSec / 3600
val min = elapsedInSec / 60 - hou * 60
val sec = elapsedInSec % 60
Tripl字体规划e(hou, minCanvas, sgoogle网站登录进口ec)
}
...
字体动态改动
剩余时刻的改动,带来文字内容和字体大小不同。这个完毕十分简略,只需Composable中设置size
的时分判别剩余时刻就好了。
//依据剩余时刻设置字体大小
val (sizegoogle谷歌查找主页, lab字体规划elSize) = when {
hou > 0 -> 40.sp to 20.sp
min > 0 -> 80.sp to 30.sp
else -> 150.sp to 50.sp
}
...
Row() {
if (hou > 0) {//当剩余时刻短少一小不时,不闪现h
DisplayTime(
hou.fo字体大师rmatTime(),
"h",
fontSize = size,
labelSize = labelSize
)
}
if (min > 0) {//剩余时刻短少1分钟,不闪现m
DisplayTime(
min.formatTime(),字体全国
"m",
fontSize = size,
labelSize = labelSize
)
}
DisplayTimcanvas标签e(
sec.f字体ormatTime(),
"s",
fontSize = size,
labelSize = labelSize
)
}
气氛动画
气氛动画对进步App质感很重要,app中运用了如下几种动画烘托气氛:
- 正圆呼吸灯作用:1次/2秒
- 半圆环跑马灯作用字体转换器:1次/1秒
- 雷达动画:倒计时完毕时扫描发展100%
- 文字缩放:倒计时10秒缩放,1次/1秒
这儿运用transition
同步多个动画
v字体美化大师免费下载al transition = rem字体美化大师免费下载emberInfiniteTransition()
var trigger by remember { mutableStateOf(0f) }
//线性动画完毕雷达动画
val animateTween by animateFloatAsState字体规划(
targetValue = trigger,
animationSpec = tween(
durationMillis = durationMills,
easing = LinearEasing
),
)
//infiniteRepeatable+restart完毕跑马灯
val animatedRestaapp装置下载rt by transitiongoogle查找引擎进口口.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpeandroid是什么手机牌子c = infinitegoogle查找引擎进口口Repeatable(tween(1000), RepeatMode.Restandroid的drawable类art)
)
//infiniteRepeatable+rever字体大小怎么调se完毕呼吸灯
val animatedReverse by transition.animateFloat(
initialValue = 1.05f,
targetValue = 0.95f,
animationSpec = infiniteRepeatable(tween(2000), RepeatMode.Reverse)
)
//infiniteRepeatable+reverse完毕文字缩放
val animatedFont by transition.animateFloat(
initialValue = 1.5f,
targetValue = 0.8f,
animationSpec = infiniteRepeatable(tween(500), RepeatMode.Reverse)
)
-
rememberInfiniteTransition
创立了一个repeatable的transition
,transition经过animateXXX
创立多个动画(state),同一个transition创立的动画坚持同步。app中创立了3个canvas中文动画:animatedRestart
、animatedReverse
、animatedFont
- transition中也能够android/yunos设置animationSpec。app中配备的
infandroid/yunosiniteRepeatable
是一个repeat动画,能够经过参数设置duration
以及RepeatMode
制字体美化大师免费下载造圆环图形
接下来就能够依据上面创立的动画state制作各种圆形的气氛了,经过不断地compoition完毕动画作用。
Canvas(字体全国
modifier = Modifier
.align(CanvasAligngooglement.Centergoogle)
.padding(16.dp)
.siandroid什么意思ze(350.dp)
) {
val diameter = size.mcanvas软件inDimension
val radius = diameter字体美化大师 / 2f
val size = Size(radius * 2, radius * 2)
//android平板电脑价格跑马灯半圆
drawArc(
color = color,
startAngle = animatedRestart,
sweepAngle = 150f,
size = size,
style = Stroke(15f),
)
//呼吸灯整圆
drgoogle服务结构awCircle(
color = secondColor,
style = strokeReverse,
radius = radius * aandroid的drawable类nim字体大师atedReverse
)
//雷达扇形
drawArc(
startAngle = 270f,
sweepAngle = animateTween,
brush = Brush.radiagooglelGradiCanvasent(
radius = radius,
colors = listOf(
purple200.copy(0.3f),
teal200.copy(0.2f),
Color.White.copy(0.3f)
),
),
useCenter =android的drawable类 true,
sgoogle查找引擎进口口tyle = Fill,
)
}
-
Canvas{}
能够制作自界说图形。Android -
drawArc
用来制作一个带角度的弧形,startAngle
和sweepAngle
设置弧在圆上的 其实方位,这儿设置startAngle为animatedRestart
,依据state的改动完毕动画作用。style设置为Stroke
表明只制作边框,设置为Fill
则表明填充这个Canvas弧形区域构成扇形。 -
drawCircle
用来制作一个正圆,这儿经过animatedReverse
,改动半径完毕呼吸灯作用
Note: 关于Compose动画的更多内容能够参看 《一文学会运用Jetpack Compose Animations》
# 总结
Compose的中心是Standroid下载软件appate驱动Uandroid什么意思I改写,animatiappstoreon也是googleplay依托state来完毕动画。因此apple除了服务于视觉作用,animation还能够用来核算state。到这时才恍然大悟组织方在标题描绘中提示可能会用到animation,其更主要的目的是用来准确核算countdown的最新情况。
CountdownTimer这样的项目很合适拿来给新技google翻译术练手,第二周应战截止日是3月10日,而且后边还有两个应战,都是以鼓励新手为主所以难度应该不会很高。假定你还没有触摸过Compose,无妨趁这个机遇尝尝鲜吧~
项目appearance地址:TikTik