Flutter 改善套娃地狱问题(仿喜马拉雅PC页面举例) (2)

图片因为尺寸限制,没能展示全部内容,右边的信息流模块还有一些信息没展示出来:最新精选、热门主播、经典免费榜、有声书免费榜、相声评书免费榜。

建议各位彦祖,下载下window安装包,安装体验下;MacOS的于晏们,你们可以看看web展示效果,没有苹果那一套东西,又不想折腾黑苹果,实在打包不了。

咱们马上来看看怎么搞规范代码吧!复杂的模块,让你的代码也能高度可维护!

开搞 分析

Android的业务自定义View

在Android里面有个页面分模块的开发思路,将整个页面划分成几个业务的自定义View,我们只需要关注传入数据源,和对应业务View交互事件回传信息,这明显是外观模式的思想。。。关注了:数据源和交互事件即可,其它的一切都不是我们所关心的,然后主页面里面,组合下这些业务view就OK了,彻底抛弃include坑比做法,include让xml也耦合了,如果改动了一个被多处引用的xml,可能会引发的一些影响,大家心里可以揣摩揣摩。

Flutter的Widget

然后再结合Flutter中那些众多的系统widget,系统那些Widget基本都属于功能性的Widget,需要定义巨量的字段传值,这样的好处,就是能够非常颗粒的去控制需要的字段,再配合一些定义的回到函数,就能起到:数据源和交互回调的完美组合。

结合上面的业务View和一切皆Widget的思路,我们可以得出一个结论:搞业务Widget,然后再进行组合!

当然,咱们在这里得出了一个不是结论的结论,一般来说,这种操作是咱们基本素养,但是具体的操作细节上,还是有很多需要注意的:

业务Widget,也需要划分模块

Column,Row之类有着天然结构,怎么去利用

旁枝末节的Widget细节,怎么去封装

主模块封装

上面咱们一通分析猛如虎后,得出一个结论:搞业务Widget!

关于业务Widget的封装细节,这里说明下:

数据源尽量只使用一个,不要使用过多字段去划分

解释下,因为我们这是业务性widget,并不是功能性widget,过渡的细分字段输入,会导致你封装的widget过长,业务Widget很多时候,只会在你这个模块,其它模块一般都很少用的,没必要去过度的细分字段,开发多了你就会发现,你封装的那些业务Widget,百分之95的概率,只会在你自己写的那个页面吃灰一辈纸。。。

如果是比较通用的widget,那就可以细分字段了或者使用中间实体都OK!通用的模块开发,关于数据源输入,就需要考虑一些比较通用的数据格式,例如只需要一个list数据,就不要搞一个实体,只需要一个字段,就不需要搞一个list等等。。。

交互事件,必须使用回调函数,保留出来

关于交互事件,这里必须要保留出来,给业务层或者逻辑层去处理;一般来说,用户进入该页面,点击或滑动页面,就是业务事件产生的时候了,这是必须暴露出来的,切记切记。

仿造的喜马拉雅主模块

来看看仿造的喜马拉雅PC页面主模块的代码

这里使用了一点Getx知识,如果你不了解,可查询此文章:Flutter GetX使用---简洁的魅力!

组装对应的业务Widget的时候:请记住,对应的业务Widget一定要写上注释

下面就是主模块的所有代码,大家摸着良心说说:

这还死亡嵌套吗?

这还俄罗斯套娃吗?

这看着还恐怖吗?

其实按照下面的封装,基本是把View和Event做了一个结合了

所有业务Widget的入口,可快速定位到需要修改的业务Widget

所有的事件交互触发入口,一眼可见,能快速的定义相应业务

class HimalayaPage extends StatelessWidget { final HimalayaLogic logic = Get.put(HimalayaLogic()); final HimalayaState state = Get.find<HimalayaLogic>().state; @override Widget build(BuildContext context) { return himalayaBuildBg(children: [ //顶部:左边侧边导航栏 + 右边信息流 himalayaBuildTopBg(children: [ //左边导航栏 HimalayaLeftNavigation( data: state, //导航栏item回调 onTap: (Rx<HimalayaSubItemInfo> item) => logic.navigationItem(item), ), //右边信息流 himalayaBuildInfoListBg(children: [ //顶部搜索框及其一些个人信息设置按钮 HimalayaPersonalInfo( //搜索框输入监听 onChanged: (String msg) => logic.onSearch(msg), //左箭头 onLeftArrow: () => logic.dealLeftArrow(), //右箭头 onRightArrow: () => logic.dealRightArrow(), //刷新按钮 onRefresh: () => logic.onRefreshData(), //皮肤按钮 onSkin: () => logic.switchSkin(), //设置按钮 onSetting: () => logic.onSetting(), ), //右侧信息流 - 可滑动部分 himalayaBuildScrollInfoListBg(children: [ //轮播图 HimalayaBanner( data: state.bannerList, //具体banner的监听 onTap: (int index) => logic.clickBanner(index), ), //猜你喜欢 HimalayaGuess( data: state.guessList, //换一批 onChange: () => logic.guessChange(), //猜你喜欢具体卡片 onGuess: (HimalayaSubItemInfo item) => logic.guessDetail(item), ), //最新精选 HimalayaNewest( data: state, //分类标题 onSortTitle: (item) => logic.sortTitle(item), //具体精选卡片 onNewest: (HimalayaSubItemInfo item) => logic.onNewest(item), ), //热门主播 HimalayaAnchor( data: state.anchorList, onAnchor: (HimalayaSubItemInfo item) => logic.hotAnchor(item), ), //各类榜单 HimalayaRankList( data: state.rankList, //标题 onTitle: (String title) => logic.rankTitle(title), //榜单上具体item onItem: (HimalayaSubItemInfo item) => logic.rankItem(item), ), ]), ]), ]), //底部:音频播放控制台 HimalayaAudioConsole( data: state.audioPlayInfo, //左切换 onLeftArrow: () => logic.onLeftArrow(), //播放 onPlay: () => logic.onPlay(), //右切换 onRightArrow: () => logic.onRightArrow(), //喜欢 onLove: () => logic.onLove(), //播放模式 onPlayModel: () => logic.onPlayModel(), //封面 onCover: () => logic.onCover(), //进度 onProgress: () => logic.onProgress(), //音量 onVolume: () => logic.onVolume(), //标题 onSubtitle: () => logic.onSubtitle(), //倍速 onSpeed: () => logic.onSpeed(), //定时 onTiming: () => logic.onTiming(), //目录 onCatalog: () => logic.onCatalog(), ), ]); } } 主体细节封装

一般来说,一个页面整体基本上是横向(Row)或者纵向(Column)的结构

咱们仿造的喜马拉雅模块也是属于纵向结构:上下俩大模块

上模块:导航栏 + 信息流 => 又分左右模块

左模块:左边的侧面导航栏 => 很明显的纵向布局

右模块:信息流 => 这就是简单的纵向结构,从上到下了

下模块:音频播放栏 => 完全就是横向布局了

通过上面的说明,很明显,Row和Column中children属性才是我们所关注的,其它的细节描述封装起来即可

主模块的很多主体细节,是完全可以封装起来,新建一个(模块名_function)文件:

himalaya_function.dart:主体部分有很多无需关注的细节,统一放在这个模块,此处,只需要暴露一个children属性即可

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsyfg.html