Flutter学习:Drawer和水纹按压效果
分享的是一个常用功能——水纹按压效果,效果如下:

这个效果就是安卓手机常见的按压水纹效果。
例子
看完效果,我们开始进入写例子的环节,其实例子就是上图,是我模仿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() {
List<Widget> drawerOptions = [];
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: <Widget>[
Container(
height: 100,
margin: EdgeInsets.fromLTRB(16, 32, 0, 0),
child: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[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: <Widget>[
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的嵌套,从而达到酷炫的效果。优点是可以组合各种各样的效果,缺点则是嵌套地狱。
仓库
点击flutter_demo,查看完整代码。
作者:少年阿涛
链接:https://juejin.im/post/5cf3a503e51d4555fd20a2e2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
THE END