首先说明的是 ViewControler 并不是 Android 中存在的一个组件,而是在技术实践中总结创造出的一个开发理念,这是一种业务开发过程中的 UI 模块化思想的体现,依附于现成的 Activity 或者 Fragment 而存在。在特定的场景下使用 ViewControler ,会使你原本复杂的界面开发逻辑变得清晰明了,易于维护。下面进入正题。

场景介绍

先简单介绍一种常见的界面开发情形。

示例

在我们日常 Android 开发过程中经常会看到类似下面这样的 UI 界面。如下,这是一个普通的房屋详情页面。

一个简单的房屋详情示意界面

在实际的开发中,这种看上去长长的详情界面比比皆是,上面只是自己简单用画图板画的一个房屋详情示意界面。

简单介绍下这个界面。如图所示,最上面是一个用于展示房屋图片的画廊区域,下面是房屋基本信息展示块,下面是房屋最近几月的价格走势图,下面是房屋评论,实际开发中,下面可能还会有各种各样的功能模块,如户型区域之类的。

总之,一般的详情页大都很长,而且页面里可能会有各种各样的 View 元素,上面的示意图还好,整体就是四个 View 块,还不算太多,但是实际开发中,我们拿到的设计图可能比这长多了。

从产品角度详情页就是这样,大而全,用户就是要看到最详尽的信息展示,但是具体到编码实现时,我不知道大家遇到这样的页面后会怎么编码实现。其实在写这篇文章时,我特别想知道大家在实际开发这样的长页面时会采用什么样的方式去开发,如果你有自己独特的实践方法,欢迎在评论区评论。

一般做法

通常,按照一般的想法,尽管这个页面比较长,但它依旧是一个普通的不能再普通的 Activity 或者 Fragment,具体要开发这样的界面,先写好 Layout 文件,然后在 Activity 中初始化 View、接着处理业务逻辑。

问题

对于上面说到的一般做法,应对实际开发中 80% 的界面开发都没有特别大什么问题,但是,如果是上面提到的详情界面开发,就会有如下的问题。

由于这个界面比较长,我们在写 layout 时可能就会发现一个问题,layout文件太复杂了,如果界面布局比较简单还好,但是只要复杂点,这个layout 就会变得异常复杂,相信对大多数开发人员都有过类似的体验,当 layout 变得复杂,后续的 UI 调试或者需求变更,都会变得很痛苦,你需要在 layout 文件内定位到合适的位置,然后调试或者修改。

当然,说到这里。你可能会说用 include 后者 merge标签啊,当然可以,假设你使用了 include 标签已经解决了 layout 文件过于复杂的问题,那我们接着讨论业务逻辑代码的问题。

气喘吁吁的写完了 layout,终于可以写会业务代码了,我们开心的切换文件到具体的 activity,准备进行具体的业务代码开发,但面对这样的长页面,单单申明 View成员变量,就需要申明一大串,接着你要处理各中 View 的初始化以及更新,还可能要处理数据变化等等逻辑,详情页的逻辑会变得越来越复杂。对于这样的详情页面,可以预见的是,代码会超级多。

面对这样的页面,如果你是一个新人,后续需要你负责开发迭代,不得不说是一件很痛苦的事,自己也经历过,当你为一个复杂页面增加新功能,或者修改 bug,你往往先需要理解一下整个页面逻辑,接着才可以修改。没有人会喜欢阅读动不动就两三千行的 Activity 代码的。Activity 两三千行??这一点也不夸张。

思考

到这里,面对这种稍微复杂的页面开发,你已经发现用这种最原始的开发方式暴露出的问题了,代码堆积问题,维护问题。现在不仅 layout 文件管理起来麻烦,更重要的是 Acticvity 里的代码也变得难以维护。

一般的,我们遇到这种问题可能会持有两种态度。一:既然别人能开发的出来,我就可以维护,就是稍微费劲点,多读几遍代码,还是能看懂的,加班加点还是可以开发完的,只要完成,以后爱谁开发谁开发,我再也不碰了。典型的得过且过心态。另一种:

灵机一动

上 MVP,MVP 为解耦而生,是时候祭出 MVP 了。

嗯,现在的情形,使用 MVP 确实可以解决  Activity 臃肿的问题,使用 MVP 后可以把 DetailActivity 中的业务逻辑代码都移到对应的 Presenter 中去,Activity 中剩下的只有 view 操作方法或者监听方法。这样 Activity 确实瘦了不少。但是这不是解决问题的根本,Layout 文件依旧很复杂,同时 Activity 中虽然把业务逻辑代码成功迁移到了 Presenter 中,但是很多 view 的操作逻辑代码还是在Activity。

那说了这么多,到底有什讲么办法可以解决上面提到的问题!

终极大招

模块化— 将一个大的复杂界面拆分为若干子界面模块,这里需要通过一种恰当的代码组织方式去帮助我们实现一个子界面模块,这种所谓的恰当的模式就叫 ViewController ,通过 ViewController 我们可以把一个布局和业务逻辑封装为一个模块,Activity 只需要拿到这个模块的实例,就可以操作这个模块。

在 ViewController 的帮助下,我们面对这种复杂页面,只要做好模块划分,那么每一个模块对应一个 ViewController 实例,Activity 或 Fragment 只要持有他们的集合,就可以方便的操作控制他们。有木有很灵活,很轻量。

当你真的使用它之后,你会发现他带来的便利其实不仅仅实现了模块化。特别感谢之前的 Leader 对 ViewController 这种思想给予最初的启发和引导。

关于开源

目前代码已开源,项目地址。