【Flutter小技巧09】--- Flutter自定义图片显示组件
📃 需求是学习技术最有效的动力
一、前言:遇到这样的一个需求,图片展示,最多显示3张,超过3张,最后一张显示蒙版加上剩余的张数。效果图如下:
二、实现:为了好扩展,我这边做了多个组件的拆分。 1、单张图片的组件 2、多张图片的组件 3、最后一张蒙版的组件 4、判断组合 三、具体实现: 1、单张图片的组件
/// 网络图片组件 NetWorkImageWidget是我封装的一个网络图片
Widget _buildNetWorkImageWidget(int index) {
return NetWorkImageWidget(
Constant.default_url,
width: (ScreenUtils.screenWidth() - 78) / 3,
height: (ScreenUtils.screenWidth() - 78) / 3,
borderRadius: BorderRadius.all(Radius.circular(8)),
);
}
2、多张图片的组件
/// 组件 考虑固定不变的,不采用滑动组件,
Widget _buildMoreImageWidget(int imageCount) {
return imageCount == 1
? _buildImageItemWidget(0)
: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_buildImageItemWidget(0),
PaddingWidget(
left: 8,
),
imageCount >= 2 ? _buildImageItemWidget(1) : Container(),
PaddingWidget(
left: 8,
),
imageCount >= 3 ? _buildImageItemWidget(2) : Container(),
],
);
}
3、最后一张蒙版的组件
/// 阴影层
Widget _buildShadowWidget(int index) {
return (imageList!.length > 3 && index == 2)
? Container(
width: (ScreenUtils.screenWidth() - 78) / 3,
height: (ScreenUtils.screenWidth() - 78) / 3,
decoration:
WMDecorations.setBoxDecoration(8, color: Color(0x66000000)),
alignment: Alignment.center,
child: TextWidget(
'+${imageList!.length - 3}',
style: WMTextStyle.setTextStyle14(),
),
)
: Container();
}
4、判断组合
Widget _buildImageWidget() {
int imageCount = imageList!.length;
if (imageCount == 0) {
return Container();
} else {
return Container(
margin: const EdgeInsets.only(
bottom: 12,
left: 16,
right: 16,
),
height: (ScreenUtils.screenWidth() - 78) / 3,
// color: Colors.blue,
child: _buildMoreImageWidget(imageCount));
}
}
5、完整的实现,可直接使用,只要传图片数组即可,点击图片的回调。
class CareTemplateImageWidget extends StatelessWidget {
final List? imageList;
final WMIntCallBack? selectedImageCallBack;
const CareTemplateImageWidget(
{Key? key, this.imageList, this.selectedImageCallBack})
: super(key: key);
@override
Widget build(BuildContext context) {
return _buildImageWidget();
}
Widget _buildImageWidget() {
int imageCount = imageList!.length;
if (imageCount == 0) {
return Container();
} else {
return Container(
margin: const EdgeInsets.only(
bottom: 12,
left: 16,
right: 16,
),
height: (ScreenUtils.screenWidth() - 78) / 3,
// color: Colors.blue,
child: _buildMoreImageWidget(imageCount));
}
}
/// 组件 考虑固定不变的,不采用滑动组件,
Widget _buildMoreImageWidget(int imageCount) {
return imageCount == 1
? _buildImageItemWidget(0)
: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_buildImageItemWidget(0),
PaddingWidget(
left: 8,
),
imageCount >= 2 ? _buildImageItemWidget(1) : Container(),
PaddingWidget(
left: 8,
),
imageCount >= 3 ? _buildImageItemWidget(2) : Container(),
],
);
}
/// imageItem组件, 当index=2的时候做一个判断,减少组件的创建
Widget _buildImageItemWidget(int index) {
return GestureDetectorWidget(
child: index == 2
? Stack(
children: [
_buildNetWorkImageWidget(index),
_buildShadowWidget(index)
],
)
: _buildNetWorkImageWidget(index),
clickCallBack: () {
if (selectedImageCallBack != null) {
selectedImageCallBack!(index);
}
},
);
}
/// 网络图片组件
Widget _buildNetWorkImageWidget(int index) {
return NetWorkImageWidget(
Constant.default_url,
width: (ScreenUtils.screenWidth() - 78) / 3,
height: (ScreenUtils.screenWidth() - 78) / 3,
borderRadius: BorderRadius.all(Radius.circular(8)),
);
}
/// 阴影层
Widget _buildShadowWidget(int index) {
return (imageList!.length > 3 && index == 2)
? Container(
width: (ScreenUtils.screenWidth() - 78) / 3,
height: (ScreenUtils.screenWidth() - 78) / 3,
decoration:
WMDecorations.setBoxDecoration(8, color: Color(0x66000000)),
alignment: Alignment.center,
child: TextWidget(
'+${imageList!.length - 3}',
style: WMTextStyle.setTextStyle14(),
),
)
: Container();
}
}
6、实现效果如下:
四、点点滴滴都是记录的过程。 下一期分享图片浏览器。
转载自:https://juejin.cn/post/7022247907612950558