小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
| Flutter小技巧目录 | |
|---|---|
| 【Flutter小技巧01】--- TextField文本垂直居中 | |
| 【Flutter小技巧02】Flutter环境变量配置 | |
| 【Flutter小技巧03】-- 常见报错记录 | |
| 【Flutter小技巧04】--- Flutter架构设计 | |
| 【Flutter小技巧05】--- Flutter混编集成方案探讨 |
📃 需求是学习技术最有效的动力
前言:需求是不是的变化,作为开发要时刻应变需求的变化而改变。今天遇到一个折叠头像的需求。吗毛玻璃头像+折叠头像+新消息数量,先看效果图:
实现: 第一步:实现折叠头像效果;
Positioned 组件可以实现折腾效果:off是位置的变化,这里封装了一个方法,折叠头像+毛玻璃效果
/// 折叠头像
/// itemType 是我根据需求实现的头像类型,我这边喜欢和来访,count是头像的个数
List<Widget> _getStackItems(MessageHeaderItemType itemType, int count) {
List<Widget> _list = [];
for (var i = 0; i < count; i++) {
double off = 20.0 * i;
_list.add(Positioned(
left: off,
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 1),
borderRadius: BorderRadius.circular(15),
),
child: Stack(
children: <Widget>[
//约束性盒子
Container(
decoration:
Style.setBoxDecoration(15, color: Colors.transparent),
child: AvatarWidget(
itemType == MessageHeaderItemType.LikeMe
? likeHeadList.isNotEmpty
? likeHeadList[i]?.user_info?.header_url ??
Constant.defaultAvatarUrl
: Constant.defaultAvatarUrl
: visitingHeadList.isNotEmpty
? visitingHeadList[i]?.user_info?.header_url ??
Constant.defaultAvatarUrl
: Constant.defaultAvatarUrl,
width: 30,
height: 30,
fit: BoxFit.fill,
borderRadius: BorderRadius.circular(15),
),
),
Center(
//可裁切的矩形
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
//背景过滤器
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
child: Opacity(
opacity: 0.5,
child: Container(
width: 30.0,
height: 30.0,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(15),
),
),
),
),
),
)
],
),
),
));
}
return _list;
}
第二步:实现头像毛玻璃效率;
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 1),
borderRadius: BorderRadius.circular(15),
),
child: Stack(
children: <Widget>[
//约束性盒子
Container(
decoration:
Style.setBoxDecoration(15, color: Colors.transparent),
child: AvatarWidget(
itemType == MessageHeaderItemType.LikeMe
? likeHeadList.isNotEmpty
? likeHeadList[i]?.user_info?.header_url ??
Constant.defaultAvatarUrl
: Constant.defaultAvatarUrl
: visitingHeadList.isNotEmpty
? visitingHeadList[i]?.user_info?.header_url ??
Constant.defaultAvatarUrl
: Constant.defaultAvatarUrl,
width: 30,
height: 30,
fit: BoxFit.fill,
borderRadius: BorderRadius.circular(15),
),
),
Center(
//可裁切的矩形
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
//背景过滤器
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
child: Opacity(
opacity: 0.5,
child: Container(
width: 30.0,
height: 30.0,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(15),
),
),
),
),
),
)
],
),
)
第三步:实现右上角消息数量提示;
使用badges插件 轻松搞定:可以自己封装下。
附:完整代码:封装的方法,可以直接使用,实现了三个需求:头像毛玻璃+头像折叠效果+消息提示。
/// 头像
Widget _buildHeadRedWidget(MessageHeaderItemType itemType, int unCount) {
int count = 1;
if (unCount == 1) {
count = 1;
} else if (unCount == 2) {
count = 2;
} else {
count = 3;
}
return Container(
height: 30,
width: 70,
alignment: Alignment.center,
child: BadgeWidget(
unCount: unCount,
position: BadgePosition.topEnd(
top: -7,
end: count == 1
? 13
: count == 2
? 5
: unCount >= 10
? -12
: -5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
// 30 50 70
width: count == 1
? 30
: count == 2
? 50
: 70,
child: Stack(
children: _getStackItems(itemType, count),
),
),
],
),
),
);
}
/// 折叠头像
List<Widget> _getStackItems(MessageHeaderItemType itemType, int count) {
List<Widget> _list = [];
for (var i = 0; i < count; i++) {
double off = 20.0 * i;
_list.add(Positioned(
left: off,
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 1),
borderRadius: BorderRadius.circular(15),
),
child: Stack(
children: <Widget>[
//约束性盒子
Container(
decoration:
Style.setBoxDecoration(15, color: Colors.transparent),
child: AvatarWidget(
itemType == MessageHeaderItemType.LikeMe
? likeHeadList.isNotEmpty
? likeHeadList[i]?.user_info?.header_url ??
Constant.defaultAvatarUrl
: Constant.defaultAvatarUrl
: visitingHeadList.isNotEmpty
? visitingHeadList[i]?.user_info?.header_url ??
Constant.defaultAvatarUrl
: Constant.defaultAvatarUrl,
width: 30,
height: 30,
fit: BoxFit.fill,
borderRadius: BorderRadius.circular(15),
),
),
Center(
//可裁切的矩形
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
//背景过滤器
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
child: Opacity(
opacity: 0.5,
child: Container(
width: 30.0,
height: 30.0,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(15),
),
),
),
),
),
)
],
),
),
));
}
return _list;
}
未实现的时候需要考虑下,实现了就觉得不难,只为记录开发中的点滴...