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

2019-08-11 10:48:34 +08:00
 KunMinX

很现实的需求:

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

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

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

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

7770 次点击
所在节点    Android
17 条回复
lianyue13
2019-08-11 11:05:40 +08:00
google 不是有个 navigation 么
ssynhtn
2019-08-11 12:07:52 +08:00
不搞这种旁门左道,估计 Google 自己都不用
而且,你用了这种单 activity 架构,以后别人接手项目了还要再适应它才能上手
maninfog
2019-08-11 12:17:13 +08:00
单 activity 也叫少 activity,并不是说非得一个 activity 吧,只是这样叫而已。并且我觉得要做到这个需要产品和 UI 也要有相应的配合,不然实现起来好麻烦。个人项目可以玩一玩。
William911
2019-08-11 12:20:50 +08:00
对的, 自己封装一个
KunMinX
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
2019-08-11 12:36:57 +08:00
公司用的是 navigation
没啥大问题,replace 也没管。。
KunMinX
2019-08-11 12:40:04 +08:00
@winterbells

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

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

嗯 Navigation 我再多研究研究。。
narmgalaxy
2019-08-11 13:08:35 +08:00
Android 版的 telegram 就是很好的单 activity 范例,它的绝大部分页面都是由一个 activity 承载,而且它不是使用谷歌官方的 fragment,而是自己维护了一个 fragment。
KunMinX
2019-08-11 13:09:49 +08:00
@narmgalaxy 多谢,我看看
DeweyReed
2019-08-11 13:15:38 +08:00
Telegram 那是黑科技,一个文件一万多行的代码,Github 都显示不下还得下载到本地看。。
Navigation 坑不少,但就是想用。。Fragment 真是缝缝补补又一年。
narmgalaxy
2019-08-11 14:11:28 +08:00
@DeweyReed 其实还好,大部分代码量大,很大程度上是因为它没有使用 xml 来描述界面,而是使用代码直接进行构建的。在这一点上其实是对 view 的显示有一定程度的优化。避免了对 xml 的解析造成的性能损耗。
wjh3936
2019-08-11 19:05:15 +08:00
印象中以前的知乎不也是么,但是后来默默地改了
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
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
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 的主页引导访客到该项目。😉

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/590889

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX