1
IsNotGood OP 说说最近开发的应用吧,是一个单 activity 多 screen ( com pose 页面)组成的。
架构:MVI inject:dagger hilt network:retrofit data:Room 、data store task:work manager navigation:compose-destinations ,这是国外一个开源封装库,简化了 compose navigation 的使用,但还是存在许多问题。 还有就是 Accompnist 了,很多 material 库都在这里边,比如下下拉刷新、page 和 flowlayout 等。 |
2
Vaspike 2022-05-24 16:22:12 +08:00
我用 jb-compose(即 Jetpack 的桌面移植版)写过一个上位机,问题我都是在 slack 里问官方的人,还蛮热心的
附上官方 kotlinlang 的 slack 链接:https://kotlinlang.slack.com/archives/CJLTWPH7S |
3
equationl 2022-05-24 16:26:26 +08:00
开了踢我一下,最近也在学 compose ,然后写了个 Gitee 的 issue 管理。
正好遇到了好多问题,大家一起交流一下。 另外,compose 现在还是有好多 bug ,不用没感觉,真开始写后才发现问题不少。 附上项目地址: https://github.com/equationl/GiteeTodo |
4
yazinnnn 2022-05-24 16:27:40 +08:00
支持,建议禁止键政黄图,宁缺毋滥
|
5
IsNotGood OP 自己也尝试对 compose 组件进行了封装,比如:右滑按钮删除、表单输入验证、时间选择器、用 canvas 绘制了图表等。其中很多东西都有参考 youtuber 大神的视频,受益匪浅!
|
6
IsNotGood OP @Vaspike 我有尝试过 desktop 版本,调用文件 api 发现弹出的界面是 java swing 那一套,然后我瞬间没有开发欲望了
|
8
IsNotGood OP 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168
|
9
IsNotGood OP @Vaspike 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168 ,大大有兴趣可以加入下
|
10
IsNotGood OP @equationl 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168 ,大大有兴趣可以加入
|
11
IsNotGood OP @yazinnnn 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168 ,大大有兴趣可以加入
|
12
lisongeee 2022-05-24 16:50:52 +08:00
有一个困惑已久的问题想问一下,我看 compose 的路由和 react-router/vue-router 一样,是替换渲染的路由,也就是说 push 到一个新界面后之前的页面就被销毁了,而之前的 activity 路由模式,是 push 到一个新界面后之前的界面 会 onPause ,状态都在。
比如 compose-Navigation/react-router/vue-router 都不可能实现 https://stackoverflow.com/questions/72070174/ 这种效果, 那么想问一下,老哥你在开发的过程中会注意这种问题吗? |
13
oynix 2022-05-24 16:57:35 +08:00
抛开初衷,从效率来讲,不如直接 Google
|
15
lisongeee 2022-05-24 17:14:29 +08:00
@IsNotGood ,我没有设置什么参数,就是按照 compose-Navigation 官网的来的,那请问用 compose-Navigation 如何实现呢?
|
18
mxalbert1996 2022-05-24 17:42:44 +08:00 via Android
不如直接在 Kotlin 官方 Slack 的 compose 频道问,那里还有不少 Google 员工出没。
|
19
mxalbert1996 2022-05-24 17:43:37 +08:00 via Android
|
20
lisongeee 2022-05-24 17:55:44 +08:00
@mxalbert1996 不可以实现,我之前试过了
compose-Navigation 下 比如你在页面 A 的协程作用域内 val scope = rememberCoroutineScope() scope.launch{ while(true){ delay(3000) log('xxx') } } 然后你 controller.navigate('B') 控制台就不会输出了,因为 页面 A 内的局部状态都被销毁了 |
21
WebKit 2022-05-24 18:01:58 +08:00 via Android
compose 现在还有很多 bug ,线上项目还是暂时观望吧
|
22
lisongeee 2022-05-24 18:05:30 +08:00
@mxalbert1996 可能是我描述不太好,你误解我的问题了,这和动画无关,是状态的保留问题
|
23
lisongeee 2022-05-24 18:21:08 +08:00
@mxalbert1996 这下更新了,可以重新看看 https://stackoverflow.com/questions/72070174/
|
24
lmshl 2022-05-24 18:22:43 +08:00
我也用 compose-jb 写过跨平台桌面程序。讲道理,体验真不错,写出了 React + Scala 的感觉。
|
25
mxalbert1996 2022-05-24 23:30:36 +08:00 via Android
@lisongeee 需要保存的 State 就用 rememberSaveable ,这样回到前页的时候就能自动恢复。如果你需要在后台运行一些处理,那你应该考虑用 ViewModel / Service / Work manager 等等。
|
26
lisongeee 2022-05-25 01:35:39 +08:00
@mxalbert1996
你还是没懂我的意思,《这样回到前页的时候就能自动恢复》?难不成我页面内部的所有状态都要用这个包裹? 我要的是不销毁,而不是自动恢复,还有 rememberSaveable 要求数据可序列化,其他数据怎么办呢?。 比如这个 ttps://stackoverflow.com/questions/72070174/ 的路由翻页效果,在滑动的过程中,同时有两个页面在渲染 compose-Navigation 当前的替换式渲染逻辑决定了无论如何也不可能两个页面同时渲染,所以不可能实现 对了,顺便说一下,这种翻页效果,Android 微信也支持,你打开朋友圈,然后手指从左边屏幕边缘向右侧滑动,滑动到屏幕一半的时候,手指暂停移动,注意现在屏幕左侧是《发现》页面,右侧是《朋友圈》界面,这是不是同时有两个页面在渲染?我要做的就是这个路由效果,这种路由模式和效果是 compose-Navigation/react-router/vue-router 不可能实现的 |
27
mxalbert1996 2022-05-25 10:15:21 +08:00
@lisongeee
是你没搞懂,或者说你把几个问题混在了一起。 关于同时渲染两个页面,我说了通过 https://google.github.io/accompanist/navigation-animation/ 可以实现,它在底层用的是 AnimatedContent ,你可以去看看 https://developer.android.com/jetpack/compose/animation#animatedcontent ,如果不能同时渲染两个页面那你以为这个动画效果是怎么实现的? 如果你想要的是返回手势(并且要求跟手)的话,那据我所知只要你用 Navigation component 就是实现不了的,哪怕你的应用是 activity-based 的。你必须自己管理路由。 关于状态的保存,是的,你页面里所有的 UI 状态都应该用 rememberSaveable 包裹,注意这里的 UI 状态不包括数据,数据应该由 ViewModel 负责。 |
28
lisongeee 2022-05-25 10:51:51 +08:00
@mxalbert1996
1.AnimatedContent ,我先看看 2.关于状态的保存, 我根本就不需要 rememberSaveable ,我只需要像 activity 栈一样层叠渲染保持不销毁就行 |
29
lisongeee 2022-05-25 11:10:13 +08:00
@mxalbert1996
https://developer.android.com/reference/kotlin/androidx/compose/animation/package-summary#AnimatedContent(kotlin.Any,androidx.compose.ui.Modifier,kotlin.Function1,androidx.compose.ui.Alignment,kotlin.Function2) Once the ContentTransform is finished, the outgoing content will be disposed 一旦动画播放完毕,之前的状态就会被销毁,所以我之前说错了, 两个页面确实在动画持续时间内同时渲染,但是持续完成后之前页面的状态就会被销毁 我要的实际上不是动画,而是像 activity 一样的层叠式的渲染栈 那现在的 b 站来说,你可以打开视频播放页面,然后点击下面的视频推荐页面的,又到了一个播放页,然后重复这个过程,按照你的说法,难道它们都是用类似 rememberSaveable 方式保存的?,并不是,它仅仅只是启动了多个 activity 实例,然后之前的 activity 进入了 PAUSE 状态,并没有 DESTROY 而 compose-Navigation 会把之前的页面全部 DESTROY ,没有 PAUSE 跟你说了大半天,你怎么老是认为我要动画? |
30
lisongeee 2022-05-25 11:14:29 +08:00
@mxalbert1996
在 多 activity 下,如果顶栈的 activity 背景是半透明的,那么可以看到 下面的 activity compose-Navigation 则不行,因为它到一个新页面就把之前的页面状态丢弃,这点和 react-router/vue-router 一样 |
31
mxalbert1996 2022-05-25 12:13:07 +08:00 via Android
@lisongeee
如果你想要的是返回手势(并且要求跟手)的话,那据我所知只要你用 Navigation component 就是实现不了的,哪怕你的应用是 activity-based 的。你必须自己管理路由。 所以你是没看到我这句话? |
32
lisongeee 2022-05-25 12:34:03 +08:00
@mxalbert1996
1.这和返回手势没关系,我就算不用手势,compose-Navigation 也实现不了,问题在于 compose-Navigation 会把之前的页面全部 DESTROY ,没有 PAUSE 2.我现在用的是自己写的路由,基于 box 布局层叠渲染,使用 key 避免重复渲染,栈的逻辑与之前的 activity 栈一致 在这种情况下页面间传递参数也变动很简单,因为我上一个页面没有被销毁 // page_a val controller = useController() val scope = rememberCoroutineScope() Button(onClick={ scope.launch { val bResult = controller.navigateForResult("page_b", params) log(bResult) // output -> "b_data" } }){ Text("go to page_b") } // page_b val controller = useController() Button(onClick={ controller.back("b_data") }){ Text("go back") } |
33
mxalbert1996 2022-05-25 14:21:46 +08:00 via Android
@lisongeee 并不是完全没关系,如果你不需要返回手势的话 Navigation Component 的这种方式是更好的选择,因为它更省资源,性能更好,生命周期管理更容易。
|
34
zoharSoul 2022-05-25 14:38:08 +08:00
|
35
mxalbert1996 2022-05-25 14:59:11 +08:00 via Android
@zoharSoul 你可能对 Android 和 Compose 开发不熟悉吧,从原来的 Activity 到现在的 Fragment 和 Compose 的方式是一种进步,而且 Navigation Component 都不支持旧方式了,如果不是有什么特殊需求我实在想不到有什么理由非要用原来的方式,而返回手势就是这特殊需求之一,所以他的这个问法给人的感觉就是因为要实现返回手势所以需要旧方式。
|
36
leek120303 2022-05-25 16:38:21 +08:00 via Android
作为一个小白,可能偶尔有一些 dockercompose 的问题问问,可以进群看看大佬吗?
|
37
zoharSoul 2022-05-25 16:54:15 +08:00
@mxalbert1996 #35 那你就正面告诉他, 解决不了不就得了呗
绕来绕去的 |
38
lisongeee 2022-05-25 17:01:02 +08:00
@mxalbert1996
compose-Navigation 当然省资源,按照它的渲染逻辑,就是 start 一个新 Activity 后立刻把当前 activity finish 掉。 自始至终都只有一个路由组件在渲染,当然省资源。 但是问题在于我们有很多局部状态,就比如 b 站的视频页,有视频播放进度,视频操作区各个按钮的显示状态,屏幕每个弹幕的位置,评论区的滑动位移,评论区有单个评论的展开状态,内部也有自己的滑动偏移,等等很多局部状态。 我想要的效果是在这个页面又打开新视频页一顿操作又打开新视频页又打开新视频页一顿操作后又返回又返回 balbala ,每个视频页面在回来的时候都是离开的样子。这正是目前 b 站的实现效果。 如果是你来用 compose-Navigation 实现,你准备怎么实现这种效果呢? |
39
IsNotGood OP @leek120303 当然可以
|
40
mxalbert1996 2022-05-25 18:36:43 +08:00 via Android
@lisongeee 有局部状态的又不是只有你这一个应用,所有应用不都有局部状态么?跟屏幕显示相关的状态(比如弹幕位置、列表位移)用 rememberSaveable ,其他状态放 ViewModel 啊,你总不至于所有处理全部放在 View 层吧?
|