导航
前言
笔者的Flutter练手项目代码都放在,有需要的可以star噢。看完觉得有帮助的话,可以动手点个赞?。
主题
今天分享的是一个常用功能——水纹按压效果,效果如下:
这个效果就是安卓手机常见的按压水纹效果。
例子
看完效果,我们开始进入写例子的环节,其实例子就是上图,是我模仿Gmail做的一个效果图:
主体框架就是安卓的Drawer效果,对于Drawer,Flutter支持的很好,使用起来很简单,如下:
@override Widget build(BuildContext context) { final currentPage = _getDrawerItemWidget(_selectedPageKey); return Scaffold( appBar: Common.appBar(title: currentPage.title), extendBody: true, drawer: _buildDrawer(), body: currentPage, ); } _buildDrawer() { ListdrawerOptions = []; widget.drawerItems.forEach((String key, DrawerItem item) => drawerOptions.add( DrawerRippleItem( iconPath: item.iconPath, title: item.title, highlightColor: item.highlightColor, contentHighlightColor: item.contentHighlightColor, isSelect: key == _selectedPageKey, tapCallback: () => _onSelectItem(key), ) )); return Drawer( child: Container( color: Colors.white, child: Column( children: [ Container( height: 100, margin: EdgeInsets.fromLTRB(16, 32, 0, 0), child: Center( child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [Common.circleAvatar(size: 64.0, path: "ic_default_avatar.webp")], ), ), ), Column(children: drawerOptions) ], ))); }复制代码
就是在Scaffold这个脚手架Widget增加一个drawer属性即可,具体我也不细讲,感兴趣可以看完整代码。
说回水纹按压,需要用到三个widget,分别是Material,Ink, InkWell。Material就是提供安卓设计风格的支持,Ink翻译过来就是油墨的意思,是水纹效果的外层容器,相当于Container,InkWell则是水纹的真实容器,其中包含水纹颜色等属性,代码如下:import 'package:flutter/material.dart';class RippleItem extends StatelessWidget { RippleItem({Key key, this.isSelect = false, this.itemHeight = 48.0, this.highlightColor = const Color(0xFFE1F5FE), this.normalColor = Colors.white, this.rippleColor, this.tapCallback, this.borderRadius = const BorderRadius.all(Radius.zero), this.content, }) : super(key: key); final bool isSelect; final double itemHeight; final Color normalColor; final Color highlightColor; final Color rippleColor; final GestureTapCallback tapCallback; final BorderRadius borderRadius; final Widget content; @override Widget build(BuildContext context) { return Material( color: normalColor, child: Ink( decoration: BoxDecoration( color: isSelect ? highlightColor : normalColor, borderRadius: borderRadius ), child: InkWell( splashColor: rippleColor != null ? rippleColor : Theme.of(context).splashColor, borderRadius: borderRadius, onTap: tapCallback, child: Container( height: itemHeight, child: content, )))); }}复制代码
可以发现在Flutter中,视觉效果就是Widget的叠加,俗称嵌套地狱。在完成了RippleItem的封装后,我在之上又加了DrawerRippleItem的封装,如下:
import 'package:flutter/material.dart';import 'package:flutter_demo/widget/ripple_item.dart';import '../common_widget.dart';class DrawerRippleItem extends StatelessWidget { DrawerRippleItem({ Key key, this.isSelect = false, this.iconPath, @required this.title, this.highlightColor, this.contentHighlightColor, this.tapCallback, }) : super(key: key); final String iconPath; final String title; final Color highlightColor; final Color contentHighlightColor; final bool isSelect; final GestureTapCallback tapCallback; final Color normalColor = Color(0xFF262d50); @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(right: 4.0), child: RippleItem( isSelect: isSelect, tapCallback: tapCallback, highlightColor: highlightColor, borderRadius: BorderRadius.only( topRight: Radius.circular(24.0), bottomRight: Radius.circular(24.0), ), content: Container( padding: EdgeInsets.only(left: 24.0), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children:[ Container( child: Common.iconImage(path: iconPath,color: isSelect ? contentHighlightColor: normalColor), margin: EdgeInsets.only(right: 24.0), ), Common.primarySmallTitle(content: title, color: isSelect ? contentHighlightColor: normalColor) ], )), ), ); }}复制代码
其实就是增加了Radius属性,形成圆角效果,到这里已经大功告成了。
总结
本篇主要介绍了Flutter的Drawer和水纹效果的简单使用,在Flutter的世界里,万物皆Widget,各种效果也是各种Widget的嵌套,从而达到酷炫的效果。优点是可以组合各种各样的效果,缺点则是嵌套地狱。
仓库
点击,查看完整代码。