V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
IsNotGood
V2EX  ›  Android

想开一个 compose 相关的群

  •  
  •   IsNotGood · 2022-05-24 16:14:43 +08:00 via iPhone · 10033 次点击
    这是一个创建于 940 天前的主题,其中的信息可能已经有所发展或是发生改变。
    大家有想法加入吗?目前加了一大堆安卓讨论区,群里很多还是 xml 那一套,估计 compose 在国内成不了主流吧。近期开发了一款应用。界面完全是 compose 写的,也遇到过很多问题,只能去 google 。
    40 条回复    2022-05-25 18:36:43 +08:00
    IsNotGood
        1
    IsNotGood  
    OP
       2022-05-24 16:21:42 +08:00 via iPhone
    说说最近开发的应用吧,是一个单 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 等。
    Vaspike
        2
    Vaspike  
       2022-05-24 16:22:12 +08:00
    我用 jb-compose(即 Jetpack 的桌面移植版)写过一个上位机,问题我都是在 slack 里问官方的人,还蛮热心的
    附上官方 kotlinlang 的 slack 链接:https://kotlinlang.slack.com/archives/CJLTWPH7S
    equationl
        3
    equationl  
       2022-05-24 16:26:26 +08:00
    开了踢我一下,最近也在学 compose ,然后写了个 Gitee 的 issue 管理。

    正好遇到了好多问题,大家一起交流一下。

    另外,compose 现在还是有好多 bug ,不用没感觉,真开始写后才发现问题不少。

    附上项目地址: https://github.com/equationl/GiteeTodo
    yazinnnn
        4
    yazinnnn  
       2022-05-24 16:27:40 +08:00
    支持,建议禁止键政黄图,宁缺毋滥
    IsNotGood
        5
    IsNotGood  
    OP
       2022-05-24 16:29:22 +08:00 via iPhone
    自己也尝试对 compose 组件进行了封装,比如:右滑按钮删除、表单输入验证、时间选择器、用 canvas 绘制了图表等。其中很多东西都有参考 youtuber 大神的视频,受益匪浅!
    IsNotGood
        6
    IsNotGood  
    OP
       2022-05-24 16:31:14 +08:00 via iPhone
    @Vaspike 我有尝试过 desktop 版本,调用文件 api 发现弹出的界面是 java swing 那一套,然后我瞬间没有开发欲望了
    Vaspike
        7
    Vaspike  
       2022-05-24 16:34:48 +08:00
    @IsNotGood #6
    桌面版与 Swing 的关系不大,但是可以嵌入 Swing 的组件
    IsNotGood
        8
    IsNotGood  
    OP
       2022-05-24 16:43:30 +08:00 via iPhone
    因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168
    IsNotGood
        9
    IsNotGood  
    OP
       2022-05-24 16:43:55 +08:00 via iPhone
    @Vaspike 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168 ,大大有兴趣可以加入下
    IsNotGood
        10
    IsNotGood  
    OP
       2022-05-24 16:44:19 +08:00 via iPhone
    @equationl 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168 ,大大有兴趣可以加入
    IsNotGood
        11
    IsNotGood  
    OP
       2022-05-24 16:44:29 +08:00 via iPhone
    @yazinnnn 因 vx 不方便管理,最终决定开个 qqqun ,7948 去掉 17168 ,大大有兴趣可以加入
    lisongeee
        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/ 这种效果,
    那么想问一下,老哥你在开发的过程中会注意这种问题吗?
    oynix
        13
    oynix  
       2022-05-24 16:57:35 +08:00
    抛开初衷,从效率来讲,不如直接 Google
    IsNotGood
        14
    IsNotGood  
    OP
       2022-05-24 17:10:09 +08:00
    @lisongeee 您想实现的效果我看可以实现啊,可能是你设置了参数导致前一页被销毁了。
    lisongeee
        15
    lisongeee  
       2022-05-24 17:14:29 +08:00
    @IsNotGood ,我没有设置什么参数,就是按照 compose-Navigation 官网的来的,那请问用 compose-Navigation 如何实现呢?
    IsNotGood
        16
    IsNotGood  
    OP
       2022-05-24 17:17:44 +08:00
    @lisongeee 您加群,我给你发个视频看看是不是您需要的需求
    lisongeee
        17
    lisongeee  
       2022-05-24 17:19:19 +08:00
    @IsNotGood 哈哈,好呀,可以深度交流一下
    mxalbert1996
        18
    mxalbert1996  
       2022-05-24 17:42:44 +08:00 via Android
    不如直接在 Kotlin 官方 Slack 的 compose 频道问,那里还有不少 Google 员工出没。
    mxalbert1996
        19
    mxalbert1996  
       2022-05-24 17:43:37 +08:00 via Android
    lisongeee
        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 内的局部状态都被销毁了
    WebKit
        21
    WebKit  
       2022-05-24 18:01:58 +08:00 via Android
    compose 现在还有很多 bug ,线上项目还是暂时观望吧
    lisongeee
        22
    lisongeee  
       2022-05-24 18:05:30 +08:00
    @mxalbert1996 可能是我描述不太好,你误解我的问题了,这和动画无关,是状态的保留问题
    lisongeee
        23
    lisongeee  
       2022-05-24 18:21:08 +08:00
    @mxalbert1996 这下更新了,可以重新看看 https://stackoverflow.com/questions/72070174/
    lmshl
        24
    lmshl  
       2022-05-24 18:22:43 +08:00
    我也用 compose-jb 写过跨平台桌面程序。讲道理,体验真不错,写出了 React + Scala 的感觉。
    mxalbert1996
        25
    mxalbert1996  
       2022-05-24 23:30:36 +08:00 via Android
    @lisongeee 需要保存的 State 就用 rememberSaveable ,这样回到前页的时候就能自动恢复。如果你需要在后台运行一些处理,那你应该考虑用 ViewModel / Service / Work manager 等等。
    lisongeee
        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 不可能实现的
    mxalbert1996
        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 负责。
    lisongeee
        28
    lisongeee  
       2022-05-25 10:51:51 +08:00
    @mxalbert1996

    1.AnimatedContent ,我先看看
    2.关于状态的保存, 我根本就不需要 rememberSaveable ,我只需要像 activity 栈一样层叠渲染保持不销毁就行
    lisongeee
        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

    跟你说了大半天,你怎么老是认为我要动画?
    lisongeee
        30
    lisongeee  
       2022-05-25 11:14:29 +08:00
    @mxalbert1996

    在 多 activity 下,如果顶栈的 activity 背景是半透明的,那么可以看到 下面的 activity

    compose-Navigation 则不行,因为它到一个新页面就把之前的页面状态丢弃,这点和 react-router/vue-router 一样
    mxalbert1996
        31
    mxalbert1996  
       2022-05-25 12:13:07 +08:00 via Android
    @lisongeee
    如果你想要的是返回手势(并且要求跟手)的话,那据我所知只要你用 Navigation component 就是实现不了的,哪怕你的应用是 activity-based 的。你必须自己管理路由。
    所以你是没看到我这句话?
    lisongeee
        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")
    }
    mxalbert1996
        33
    mxalbert1996  
       2022-05-25 14:21:46 +08:00 via Android
    @lisongeee 并不是完全没关系,如果你不需要返回手势的话 Navigation Component 的这种方式是更好的选择,因为它更省资源,性能更好,生命周期管理更容易。
    zoharSoul
        34
    zoharSoul  
       2022-05-25 14:38:08 +08:00
    @mxalbert1996
    你这理解能力看的我都着急

    人家想要的需求说的很明显了, 不是什么动画啊, 手势啊 巴拉巴拉的

    就是像原来那样的 activity 一样, 层叠是暂停而不是销毁
    mxalbert1996
        35
    mxalbert1996  
       2022-05-25 14:59:11 +08:00 via Android
    @zoharSoul 你可能对 Android 和 Compose 开发不熟悉吧,从原来的 Activity 到现在的 Fragment 和 Compose 的方式是一种进步,而且 Navigation Component 都不支持旧方式了,如果不是有什么特殊需求我实在想不到有什么理由非要用原来的方式,而返回手势就是这特殊需求之一,所以他的这个问法给人的感觉就是因为要实现返回手势所以需要旧方式。
    leek120303
        36
    leek120303  
       2022-05-25 16:38:21 +08:00 via Android
    作为一个小白,可能偶尔有一些 dockercompose 的问题问问,可以进群看看大佬吗?
    zoharSoul
        37
    zoharSoul  
       2022-05-25 16:54:15 +08:00
    @mxalbert1996 #35 那你就正面告诉他, 解决不了不就得了呗
    绕来绕去的
    lisongeee
        38
    lisongeee  
       2022-05-25 17:01:02 +08:00
    @mxalbert1996
    compose-Navigation 当然省资源,按照它的渲染逻辑,就是 start 一个新 Activity 后立刻把当前 activity finish 掉。
    自始至终都只有一个路由组件在渲染,当然省资源。

    但是问题在于我们有很多局部状态,就比如 b 站的视频页,有视频播放进度,视频操作区各个按钮的显示状态,屏幕每个弹幕的位置,评论区的滑动位移,评论区有单个评论的展开状态,内部也有自己的滑动偏移,等等很多局部状态。

    我想要的效果是在这个页面又打开新视频页一顿操作又打开新视频页又打开新视频页一顿操作后又返回又返回 balbala ,每个视频页面在回来的时候都是离开的样子。这正是目前 b 站的实现效果。

    如果是你来用 compose-Navigation 实现,你准备怎么实现这种效果呢?
    IsNotGood
        39
    IsNotGood  
    OP
       2022-05-25 18:14:21 +08:00 via iPhone
    @leek120303 当然可以
    mxalbert1996
        40
    mxalbert1996  
       2022-05-25 18:36:43 +08:00 via Android
    @lisongeee 有局部状态的又不是只有你这一个应用,所有应用不都有局部状态么?跟屏幕显示相关的状态(比如弹幕位置、列表位移)用 rememberSaveable ,其他状态放 ViewModel 啊,你总不至于所有处理全部放在 View 层吧?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2978 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:20 · PVG 22:20 · LAX 06:20 · JFK 09:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.