赞
踩
之前开发电商的功能时,需要做商品界面,UI基本是参考京东、淘宝的效果,以前android原生开发的时候觉得很好做,切到Flutter之后只能自己想办法,所以自己后来做出了这样的效果,分享下实现方案。
先看效果图吧
这是京东的效果
下图是我做的效果,基本和京东的保持一致,点击tab可快速切换到某一页,滑动列表tab自动切换。
仔细查看京东的商品详情页,可以整理出下面三点
1.tabbar随着慢慢滑动一定距离会变透明,再次滑到顶部则重新变成不透明
2.滑动的过程中,到达新的页面内容,顶部的tab下标会自动切换到当前的内容下标
3.点击tab中的某一项,页面则会自动滑动到相应页面
整体的思路其实就是最重要的一点,得到商品页的高度。得到了商品页的高度,再通过滑动事件针对偏移量进行操作,我们就可以做到上面的三件事。
上面提到最重要的是得到商品的高度,那么在flutter中如何得到widget的高度呢?我通过查询资料得到了最后的答案。获取到widget的size,从而获得它的height属性。这里还有一个坑,一些异步加载的布局,你有时候直接去拿获取不到正确值,需要等页面加载完成才能真正获取到大小。
在flutter中可以使用GlobalKey获取到控件的大小,使用 GlobalKey 的步骤如下:
1.创建globalkey对象 ,GlobalKey _globalKey = GlobalKey();
2.将widget设置globalkey属性,key: _goodsKey,
3.通过globalkey字段获取到Size
这三个步骤是获取到上面效果最关键的步骤。
还有一个就是滑动监听,这边用到了flutter的SingleChildScrollView控件中的ScrollController,通过监听回调,返回当前的偏移量,从而与商品高度进行比较更新界面。
_scrollController.addListener(() {
///此处监听滑动的偏移量
...
});
另外两个简单的逻辑是tab的切换和点击,这个flutter自带的tab控件使用方法很简单,可以自行参考。
这里只放部分代码,我会把整个demo上传到github上面去,需要的可以自己拿。
计算商品页面widget高度的代码:
///计算商品信息页的高度
void calculateHeight() {
_goodHeight =
getSize(_goodsKey.currentContext) - (Platform.isIOS ? 88 : 50);
print("calculateHeight $_goodHeight");
}
double getSize(BuildContext buildContext) {
final RenderBox box = buildContext.findRenderObject();
final size = box.size;
return size.height;
}
整体布局界面代码:
@override Widget build(BuildContext context) { return Scaffold( ///底部购买商品、购物车 bottomNavigationBar: buildBottomBar(), body: Stack( children: [ SingleChildScrollView( controller: _scrollController, child: Column( children: [ Container( key: _goodsKey, ///商品页 child: GoodsInfoPage(), ), Container( ///详情中的图片 child: _html, ), ], ), ), ///根据透明度显隐顶部的bar Opacity( opacity: toolbarOpacity, child: Container( height: 78, color: Colors.red, ///顶部显隐的bar child: buildTopBar(), ), ) ], ), ); }
还有滑动监听的处理逻辑
_scrollController.addListener(() { ///如果滑动的偏移量超出了自己设定的值,tab栏就进行透明化操作 double t = _scrollController.offset / DEFAULT_SCROLLER; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } if (mounted) { setState(() { toolbarOpacity = t; }); } ///如果滑动偏移量大于商品页高度,tab就切换到详情页 if (_scrollController.offset >= _goodHeight) { _tabController.animateTo(1); } else { _tabController.animateTo(0); } });
难度其实也不是很大,但是整体的思路和方案才是最难的,当然也有其他一些实现方式,欢迎交流。
Demo地址:https://github.com/shudaizisd/Flutter_Shop
如果有不对的地方,欢迎指出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。