flutter 图片圆角_Flutter如何实现精美UI系列视频系列1
(本视频为原创视频)Flutter如何实现如下精美UI:视频如下:效果及源码地址:web端访问:http://ijitang.net/图片地址:https://dribbble.com/shots/6574276--8-Travel-Guides-Experience-Freebie源码地址:https://github.com/jiang111/flutter_code实现思路:主要难...
(本视频为原创视频)
Flutter如何实现如下精美UI:
视频如下:
效果及源码地址:
web端访问:http://ijitang.net/
图片地址:https://dribbble.com/shots/6574276--8-Travel-Guides-Experience-Freebie
源码地址:https://github.com/jiang111/flutter_code
实现思路:
主要难点在于列表页跳转到详情页的时候图片的hero效果,以及第二个页面中的上滑效果样式的问题,一般上滑效果都会采用sliver来实现,原本采用的是
NestedScrollView + headerSliverBuilder 来实现,
但是在实现的时候发现无法做出中间以图片作为背景的白色圆角,于是才用了CustomScrollView+Slivers实现,Sliver用SliverPersistentHeader自定义DetailSliverDelegate实现,body部分采用SliverToBoxAdapter实现,部分代码如下:
hero部分:
Hero( //以url作为tag,保证不会重复 tag: bean.url, child: Stack( children: [ Padding( padding: const EdgeInsets.only(bottom: 30, right: 10), child: ClipRRect( borderRadius: BorderRadius.circular(5), child: Image.asset( bean.url, width: 170, fit: BoxFit.cover, ), ), ), Positioned( bottom: 50, left: 15, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Material( color: Colors.transparent, child: Text( bean.location, style: TextStyle( color: Colors.white, fontSize: 15, ), ), ), //...省略不重要代码 ], ), ), ),
主要的slivers部分:
CustomScrollView( slivers: [ _buildSliverHead(), SliverToBoxAdapter( child: _buildDetail(), ) ], ), //_buildSliverHead 方法 Widget _buildSliverHead() { return SliverPersistentHeader( delegate: DetailSliverDelegate( expanded_height, widget.bean, rounded_container_height, ), ); }//_buildDetail方法
DetailSliverDelegate类:
class DetailSliverDelegate extends SliverPersistentHeaderDelegate { final double expandedHeight; final TravelBean bean; final double rounded_container_height; DetailSliverDelegate( this.expandedHeight, this.bean, this.rounded_container_height); @override Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { //此处是为了实现Android中的沉浸式状态栏,以及ios的状态栏 return AnnotatedRegion( value: SystemUiOverlayStyle( statusBarColor: Colors.transparent, //使用dark模式可以让状态栏的字变为黑色,而图片是白色,这样才能看到状态栏的文字 statusBarIconBrightness: Brightness.dark, statusBarBrightness: Brightness.dark, ), child: Stack( children: [ Hero( tag: bean.url, child: Image.asset( bean.url, width: MediaQuery.of(context).size.width, height: expandedHeight, fit: BoxFit.cover, ), ), Positioned( top: expandedHeight - rounded_container_height - shrinkOffset, left: 0, child: Container( width: MediaQuery.of(context).size.width, height: rounded_container_height, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30), ), ), ), ), Positioned( top: expandedHeight - 120 - shrinkOffset, left: 30, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( bean.name, style: TextStyle( color: Colors.white, fontSize: 30, ), ), Text( bean.location, style: TextStyle( color: Colors.white, fontSize: 15, ), ), ], ), ) ], ), ); } @override double get maxExtent => expandedHeight; @override double get minExtent => 0; // 此处为0代表可以一直划上去,不出现pinned效果 @override bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { return true; }}
说明:
图片来自dribbble,如果图片侵权请联系作者删除
为什么文章中会出现广告? 写代码的也要赚点零花钱吃饭的嘛
点击原文链接可跳转至bilibili观看
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)