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

结合上面的效果图,再结合下面的代码,大家应该一眼看出来,就知道是哪个widget方法,对应界面上的哪个控件;如果你想修改哪个控件样式,直接点进对应的widget方法里修改即可

children里面的每个widget方法上面,请一定一定记得写上注释,因为此处才是业务Widget最主要的入口,具体的widget方法写不写注释无所谓了

///搜索框 个人信息 设置等按钮 class HimalayaPersonalInfo extends StatelessWidget { HimalayaPersonalInfo({ Key key, this.onRefresh, this.onLeftArrow, this.onRightArrow, this.onSetting, this.onSkin, this.onChanged, }) : super(key: key); ............. @override Widget build(BuildContext context) { return _buildBg(children: [ //左图标 _buildLeftArrow(), //右图标 _buildRightArrow(), //刷新图标 _buildRefresh(), //搜索框 _buildSearch(), //头像 _buildHeadImg(), //皮肤 _buildSkin(), //设置 _buildSetting(), ]); } .......... }

来看下其中的_buildBg方法

可以发现_buildBg主体的这些细节描述,真的是无关紧要的代码,这个写完后,基本上,后面都很少去改,所以把它提取出来后,放在墙角吃灰就行了

///搜索框 个人信息 设置等按钮 class HimalayaPersonalInfo extends StatelessWidget { ........ Widget _buildBg({List<Widget> children}) { return Container( margin: EdgeInsets.symmetric(vertical: 10.dp, horizontal: 18.dp), width: 800.dp, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: children, ), ); } }

关于方法提取

选中你需要提取的Widget代码

打开 Flutter Outline 选择左箭头图片

image-20210314214406466

填上方法命后,就能自动生成一个widget方法

如果你提取的Widget块中,还含有一些数据,自动生成的方法都会带上相应参数,非常方便

image-20210314214520198

列表类样式封装

类列表样式的封装也是比较关键的,直接从头莽尾式的提取是不行,这边有一丝调整

这里就以猜你喜欢模块举例

猜你喜欢模块

image-20210314220037075

代码分析:总体是Column布局,分上下俩模块

上模块使用Row搞定即可

下模块是四个卡片,这边是直接用的写死List数据源

///猜你喜欢 class HimalayaGuess extends StatelessWidget { HimalayaGuess({ Key key, this.onChange, this.data, this.onGuess, }) : super(key: key); .......... @override Widget build(BuildContext context) { return _buildBg(children: [ //标题 + 换一批 Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ //标题 _buildTitle(), //换一批 _buildGuessChange() ]), //显示具体信息流 _buildItemBg(itemBuilder: (item) { return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ //图片卡片 _buildPicCard(item), //文字描述 Text(item.title, style: TextStyle(fontSize: 15.sp)), //作者 Text(item.subTitle, style: TextStyle(fontSize: 13.sp, color: Colors.grey)), ]); }) ]); } .......... }

上述children代码,整体上还是比较清晰,有点迷糊的,可能就是_buildItemBg,来看看其中代码

此方法对面暴露了一个itemBuilder参数,这其实是一个回调方法

因为列表类样式,必须要遍历整个列表数据,然后,需要把列表遍历的具体数据,反向传给Widget,所以必须使用此类的回调方法

///猜你喜欢 typedef HimalayaSubBuilder = Widget Function(HimalayaSubItemInfo item); class HimalayaGuess extends StatelessWidget { ............... Widget _buildItemBg({HimalayaSubBuilder itemBuilder}) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: data.map((e) { return itemBuilder(e); }).toList(), ); } }

关于双层列表数据源(List的每个具体数据源,又含有List)又该怎么封装呢?

俩层List数据源封装是比较麻烦,这边以侧边栏举例

整个布局是一个Column:标题 + 栏目(List数据控制)

栏目:可划分具体的Item

Item:标题 + 栏目(List数据控制)

image-20210314221811228

代码实现

上面的布局整体是由数据源驱动页面,数据能控制页面item生成

///数据源:侧边导航栏目初始数据,简化了下,数据源太长了 ///该数据源都放在state层维护,此处放在这里,让大家有个对比 leftItemList = [ HimalayaItemInfo(title: '推荐', subItemList: [ HimalayaSubItemInfo( title: '发现', icon: CupertinoIcons.compass, tag: TagHimalayaConfig.find, isSelected: true, ).obs, .............. ]), HimalayaItemInfo(title: '我听', subItemList: [ HimalayaSubItemInfo( title: '我的订阅', icon: Icons.star_border, tag: TagHimalayaConfig.subscription, ).obs, ......... ]), HimalayaItemInfo(title: '我创建的听单', subItemList: [ HimalayaSubItemInfo( title: '我喜欢的声音', icon: Icons.favorite_border, tag: TagHimalayaConfig.sound, ).obs, ............ ]), ]; ///左边导航栏 class HimalayaLeftNavigation extends StatelessWidget { HimalayaLeftNavigation({ Key key, this.data, this.onTap, }) : super(key: key); ........ @override Widget build(BuildContext context) { return _buildBg(children: [ //喜马拉雅logo图标 _buildLogo(), //遍历俩层循环:不同item栏目 - 可点击,可滑动 //第一层:标题 + 子item列表 //第二层:子item详细布局 _buildItemListBg(itemBuilder: (item) { return [ //最外层item - 大标题 _buildTitle(item.title), //子栏目 - 列表 _buildSubItemListBg( data: item, subBuilder: (subItem) => _buildSubItemBg(data: subItem, children: [ //选中红色长方形条块 _buildRedTag(subItem), //图标 _buildItemIcon(subItem), //描述 _buildItemDesc(subItem), ]), ), ]; }), ]); } .......... }

第一层:来看下第一层_buildItemListBg方法

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

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