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

大家在单 Activity App 中 Fragment 是怎么管理的

  •  
  •   KunMinX · 2019-08-11 10:48:34 +08:00 · 12380 次点击
    这是一个创建于 1964 天前的主题,其中的信息可能已经有所发展或是发生改变。

    很现实的需求:

    要有 splash 页、login 页、主页,主页有 4 个 child 页,child 页的内容可以跳转到与主页平级的二级页面。

    为了做到真正的单 Activity,上述的这些页面都不得不用 fragment 编写。

    可我看到的现象是,目前流行的 Fragmentation,在单 Activity 应用支持 这方面,完全是脱离实际的,并没有把 splash 页、login 页 的情况考虑进去。

    所以想问问大家平时都是怎么实现单 Activity 的,是非得像我一样,自己封装一个 FragmentNavigation 吗?

    17 条回复    2019-08-12 17:50:36 +08:00
    lianyue13
        1
    lianyue13  
       2019-08-11 11:05:40 +08:00
    google 不是有个 navigation 么
    kx5d62Jn1J9MjoXP
        2
    kx5d62Jn1J9MjoXP  
       2019-08-11 12:07:52 +08:00 via iPad
    不搞这种旁门左道,估计 Google 自己都不用
    而且,你用了这种单 activity 架构,以后别人接手项目了还要再适应它才能上手
    maninfog
        3
    maninfog  
       2019-08-11 12:17:13 +08:00 via iPhone
    单 activity 也叫少 activity,并不是说非得一个 activity 吧,只是这样叫而已。并且我觉得要做到这个需要产品和 UI 也要有相应的配合,不然实现起来好麻烦。个人项目可以玩一玩。
    William911
        4
    William911  
       2019-08-11 12:20:50 +08:00
    对的, 自己封装一个
    KunMinX
        5
    KunMinX  
    OP
       2019-08-11 12:33:57 +08:00
    @lianyue13 @ssynhtn @maninfog

    目前正在推动 标准化架构设计 的确立。

    事实上,正因为标准化架构的确立,使得我得以在上上上周 独立承接并完成 29 个页面、34 个 API、涉及 350 余个细节 的中大型电商软件的代工。

    纯粹的单 Activity 应用的合理之处在于,让 Fragment 充当页面相比 Activity 要更加轻量、快捷。

    Activity 是面向跨进程通信的组件而设计的,是重量级的组件,所以不太适合应用内导航和跨页面的状态管理工作。

    并且像 Jetpack 中提供的 ViewModel、LiveData,在 Fragment 而不是 Activity 中能更好地发挥作用域共享的特性。

    因为出不起差错,Navigation 在这次代工中没有使用。

    Navigation 曾遇到过两个麻烦,一个是转场时的 replace。这个已通过实现自定义 Navigator 解决。
    另一个麻烦是,声明式 API 中支持的是 Tween Animation —— 一个早已被淘汰的、转场效果并不好的动画。

    打算择日在 Navigator 中用属性动画实现,只是有点复杂,需要在 Fragment 基类中,参照 Fragmentation 的 SupportFragment 实现动画完成等回调。
    winterbells
        6
    winterbells  
       2019-08-11 12:36:57 +08:00 via Android
    公司用的是 navigation
    没啥大问题,replace 也没管。。
    KunMinX
        7
    KunMinX  
    OP
       2019-08-11 12:40:04 +08:00
    @winterbells

    replace 的问题在于,每次回退时会重绘 Fragment、重新走一遍数据请求和装载的流程。这大概率地造成转场卡顿,尤其是回退到 ContainerFragment 时。除非不用转场动画。

    重新请求数据,或许可以使用 ViewModel 的大作用域状态来恢复,不过数据的装载仍然会和动画造成阻塞,导致卡顿。
    winterbells
        8
    winterbells  
       2019-08-11 12:47:35 +08:00 via Android
    @KunMinX 明显的卡顿没遇到,我们是配合 bottomsheet 来的,本来就有个加载动画。最烦的网络请求,走缓存也不是,不走也不是。。
    KunMinX
        9
    KunMinX  
    OP
       2019-08-11 13:06:01 +08:00
    @winterbells 不太明白你遇到的网络请求状况 😂

    嗯 Navigation 我再多研究研究。。
    narmgalaxy
        10
    narmgalaxy  
       2019-08-11 13:08:35 +08:00
    Android 版的 telegram 就是很好的单 activity 范例,它的绝大部分页面都是由一个 activity 承载,而且它不是使用谷歌官方的 fragment,而是自己维护了一个 fragment。
    KunMinX
        11
    KunMinX  
    OP
       2019-08-11 13:09:49 +08:00
    @narmgalaxy 多谢,我看看
    DeweyReed
        12
    DeweyReed  
       2019-08-11 13:15:38 +08:00
    Telegram 那是黑科技,一个文件一万多行的代码,Github 都显示不下还得下载到本地看。。
    Navigation 坑不少,但就是想用。。Fragment 真是缝缝补补又一年。
    narmgalaxy
        13
    narmgalaxy  
       2019-08-11 14:11:28 +08:00
    @DeweyReed 其实还好,大部分代码量大,很大程度上是因为它没有使用 xml 来描述界面,而是使用代码直接进行构建的。在这一点上其实是对 view 的显示有一定程度的优化。避免了对 xml 的解析造成的性能损耗。
    wjh3936
        14
    wjh3936  
       2019-08-11 19:05:15 +08:00
    印象中以前的知乎不也是么,但是后来默默地改了
    michaelye1988
        15
    michaelye1988  
       2019-08-12 01:13:32 +08:00
    我也你一样也是自己封装了一个框架,用来管理所有的 Fragment,不管是 login 还是 splash,都当做是一个普通的 Fragment。其中有一个类专门用来放 Fragment 的跳转入口,比如我要调整到 splash 页,那我就调用 MyFragmentManager.goToSplashFragment();就可以了。

    不太明白你说的“目前流行的 Fragmentation,在单 Activity 应用支持 这方面,完全是脱离实际的,并没有把 splash 页、login 页 的情况考虑进去” 是什么意思,这些页面我觉得单独用 Activity 写也没什么问题。

    另外,google 推出了 Navigation 可能能符合你的要求。我前段时间刚好写了几篇关于 Navigation 的文章,可以参考一下,希望能帮到你: https://zhuanlan.zhihu.com/p/69562454
    neverfelly
        16
    neverfelly  
       2019-08-12 16:16:20 +08:00
    我也和楼主遇到了类似的烦恼,找遍了 github 的 fragment 管理库,发现要么只做状态管理,要么状态管理做得半成品的同时动画管理也只做了个半成品,google 的 navigation 更是到处挖坑,只能自己写 fragment 的管理,非常期待有一个比较功能全面的 fragment 管理库
    不过对于 标准化架构设计 这个问题,activity 与 fragment 的分工职责更倾向于业务的选择,而不应该算入到架构设计这一层面的问题,纯粹的单 activity 还是会带来非常多的问题,在我自己进行开发的过程中也有考虑过纯粹的单 activity 设计,但这样会带来代码臃肿,数据通信,可维护性差,以及 fragment 多层嵌套后状态难以管理等诸多问题
    (PS. 看到作者的 ID 很眼熟,发现竟然是 Rxjava 简明魔法和 Viabus 的作者,太厉害了一直在关注,不过对于 viabus 有一点小小的看法:viabus 比起 flux-like 的架构,还是欠缺了一点简洁性,由于项目经历过少,无法判断 viabus 比起其他框架到底优秀在哪种地方
    KunMinX
        17
    KunMinX  
    OP
       2019-08-12 17:50:36 +08:00
    @neverfelly 感谢你的关注 😂

    目前在 Jetpack 状态管理框架的支持下,单 Activity 背景下的 多 fragment 通信实际上是很方便的,通过 ViewModel 就能办到。

    反倒是多 Activity 之间的通信不太方便,因为它是面向跨进程组件通信而设计的,一开始就没打算考虑组件间的实时通信(例如 在二级页面点击播放,一级页面因为生命周期的缘故得不到 唯一可信源推送的状态分发)

    而且 ViewModel 和 LiveData 是在 “架构设计面向标准化、规范化” 的背景下被设计出来的。简言之,只要用 ViewModel 和 LiveData,就算是新手,也能不自觉地实现 单向依赖 和 从唯一可信源取材并完成状态的分发,如此就能规避一系列不可预期的错误。😉



    VIABUS 更像是阉割版的 ViewModel + LiveData,说实话现如今我已不赞成在公司之外的项目中使用 VIABUS 了。

    VIABUS 的价值在于,倡导一种完全遵循设计模式 6 大原则的开发理念,即 “职责分离”,他们之间通过约定的接口,从而实现并行开发。

    但它和 MVP 有着共同的一个缺点 —— 缺乏了对状态管理的支持。使得当视图控制器重建时,无法从独立于视图控制器的单例中恢复最后一次的数据,而需要重新请求。(我司的项目是固定手机竖屏、平板横屏,所以一直以来无需考虑状态重建的问题)。

    所以,过一段时间考虑在 GitHub 开源一份 基于 jetapck 的状态管理框架 最佳实践,并在 VIABUS 的主页引导访客到该项目。😉
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1758 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 16:30 · PVG 00:30 · LAX 08:30 · JFK 11:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.