Flutter 图片选择器 SelectPhotoWidget
Posted 早起的年轻人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 图片选择器 SelectPhotoWidget相关的知识,希望对你有一定的参考价值。
在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。
如果你有兴趣 你可以关注一下公众号 biglead 来获取最新的学习资料。
先来看看本文章实现的效果
直接来看代码吧
首先是启动函数
main() {
runApp(MaterialApp(
//不显示 debug标签
debugShowCheckedModeBanner: false,
//显示的首页面
home: DemoSelectImageWidgetPage(),
));
}
然后是这个首页面,核心代码就是 SelectPhotoWidget 这个组件
///代码清单
class DemoSelectImageWidgetPage extends StatefulWidget {
@override
_DemoSelectImageWidgetPageState createState() =>
_DemoSelectImageWidgetPageState();
}
class _DemoSelectImageWidgetPageState extends State<DemoSelectImageWidgetPage> {
@override
Widget build(BuildContext context) {
//
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(title: Text("图片选择组件")),
body: Center(
child: Container(
padding: EdgeInsets.all(12),
//图片选择组件
child: SelectPhotoWidget(
header: Text(
"请选择照片",
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18),
),
//标题下的红色提醒文本
tips: "请注意 最多选择5张图片",
//图片选择回调
imageSelectAction: (List<String> list) {
print("实时选择回调${list.toString()}");
},
//最大选择图片数据
maxSelect: 6,
//预设图片
imageList: [],
),
),
),
);
}
}
将核心功能封装在了 SelectPhotoWidget 组件中,大家可以直接复制使用
///
class SelectPhotoWidget extends StatefulWidget {
///每次点击选择图片后的回调
final Function(List<String>) imageSelectAction;
///自定义标题
final Widget header;
///标题下的小捍
final String tips;
///预显示使用的图片
final List<String> imageList;
///最多可选择的图片数量
final int maxSelect;
///为true 时显示使用网络图片
final ImageType imageType;
const SelectPhotoWidget(
{Key key,
this.header,
this.tips,
this.imageList,
this.imageType = ImageType.asset,
this.imageSelectAction,
this.maxSelect = 5})
: super(key: key);
@override
State<StatefulWidget> createState() {
return _SelectPhotoWidgetState();
}
}
这里也有视频 了,大家可以来瞅瞅
class _SelectPhotoWidgetState extends State<SelectPhotoWidget>
with WidgetsBindingObserver {
///当前是否正在选择图片
bool _isSelect = false;
@override
void initState() {
super.initState();
if (widget.imageList != null) {
//判断一下最大选择图片数据
if (widget.imageList.length <= widget.maxSelect) {
_imageList = widget.imageList;
} else {
//截取图片
_imageList = widget.imageList.sublist(0, widget.maxSelect);
}
}
//绑定视图监听
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.inactive:
// 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
break;
case AppLifecycleState.resumed:
//从后台切换前台,界面可见
break;
case AppLifecycleState.paused:
// 界面不可见,后台
break;
case AppLifecycleState.detached:
// APP结束时调用
break;
}
}
@override
void dispose() {
//解绑视图监听
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
//圆角矩形剪裁
return ClipRRect(
//圆角
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Container(
color: Color(0xffFFFFFF),
//宽度填充
width: double.infinity,
//统一内边距
padding: EdgeInsets.all(10),
//垂直方向的线性排列
child: Column(
//水平方向
crossAxisAlignment: CrossAxisAlignment.start,
//包裹
mainAxisSize: MainAxisSize.min,
children: [
//标题
buildHeaderWidget(),
//第二行的小提示
buildTipsWidget(),
//显示的图片
buildGridView(),
SizedBox(
height: 10,
),
],
),
),
);
}
buildHeaderWidget() {
return widget.header != null ? widget.header : Container();
}
buildTipsWidget() {
if (widget.tips == null || widget.tips.length == 0) {
return Container();
}
return Container(
padding: EdgeInsets.only(top: 10, bottom: 16),
//圆角矩形裁剪
child: ClipRRect(
//圆角
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Container(
padding: EdgeInsets.only(left: 10, right: 10, top: 6, bottom: 6),
color: Color(0xffFFF1F1),
child: Text(
"${widget.tips}",
style: TextStyle(
color: Color(0xffBD2F2F),
fontSize: 14,
),
),
),
),
);
}
List<String> _imageList = [];
buildGridView() {
return Container(
child: GridView.builder(
padding: EdgeInsets.only(top: 8, bottom: 8),
//包裹
shrinkWrap: true,
//不可滑动
physics: NeverScrollableScrollPhysics(),
//图片个数
itemCount: getSelectCount(),
//SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 4,
//主轴间距
mainAxisSpacing: 1.0,
//从轴间距
crossAxisSpacing: 1.0,
//子组件宽高长度比例
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
//Widget Function(BuildContext context, int index)
if (index == _imageList.length) {
if (_isSelect) {
return Center(child: Text("..."));
}
return Container(
margin: EdgeInsets.only(top: 10),
child: IconButton(
icon: Icon(Icons.add),
onPressed: () {
onSelectImageFunction();
},
),
color: Color(0xFFF1F1F2),
);
}
//显示当前的图片
String imageUrl = _imageList[index];
return Container(
//层叠布局
child: Stack(
children: [
//向左下偏移一点
Positioned.fill(
top: 10,
right: 10,
child: GestureDetector(
onTap: () {
//查看大图
},
child: Container(
padding: EdgeInsets.all(1),
child: buildImageWidget(imageUrl),
color: Colors.grey[200],
),
),
),
Positioned(
top: 0,
right: 0,
child: GestureDetector(
onTap: () {
onDeleteImageFunction(index);
},
child: ClipOval(
child: Container(
padding: EdgeInsets.all(2),
color: Colors.red,
child: Icon(
Icons.close,
color: Colors.white,
size: 14,
),
),
),
),
),
],
),
);
},
),
);
}
Widget buildImageWidget(String image) {
if (widget.imageType == ImageType.net) {
return Image.network(
image,
fit: BoxFit.fitWidth,
);
} else if (widget.imageType == ImageType.asset) {
return Image.asset(
image,
fit: BoxFit.fitWidth,
);
}
return Image.file(
File(image),
fit: BoxFit.fitWidth,
);
}
///最大选择图片数据限制
getSelectCount() {
if (_imageList.length >= widget.maxSelect) {
return widget.maxSelect;
}
return _imageList.length + 1;
}
//删除照片
void onDeleteImageFunction(int index) {
_imageList.removeAt(index);
setState(() {});
widget.imageSelectAction(_imageList);
}
void onSelectImageFunction() async {
_isSelect = true;
setState(() {});
String localImageUrl = "assets/images/sp03.png";
await Future.delayed(Duration(milliseconds: 1000));
_isSelect = false;
if (localImageUrl.length > 0) {
_imageList.add(localImageUrl);
setState(() {});
widget.imageSelectAction(_imageList);
}
}
}
以上是关于Flutter 图片选择器 SelectPhotoWidget的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 表单构建器包图像选择器 Firestore Flutter