使用到的包
nine_grid_view
wechat_assets_picker
wechat_assets_picker使用前需要给相应权限,参考这篇文章
代码
ImageBean类
import 'package:nine_grid_view/nine_grid_view.dart';
class ImageBean extends DragBean {
ImageBean({
this.originPath,
this.middlePath,
this.thumbPath,
this.originalWidth,
this.originalHeight,
});
/// origin picture file path.
String? originPath;
/// middle picture file path.
String? middlePath;
/// thumb picture file path.
/// It is recommended to use a thumbnail picture,because the original picture is too large,
/// it may cause repeated loading and cause flashing.
String? thumbPath;
/// original image width.
int? originalWidth;
/// original image height.
int? originalHeight;
}
PictureUtils
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:meowfront/models/picture.dart';
class PictureUtils {
static Future<T?> pushPage<T extends Object>(
BuildContext context, Widget page) {
return Navigator.push(
context,
CupertinoPageRoute(builder: (ctx) => page),
);
}
static void showSnackBar(BuildContext context, String msg) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(msg),
duration: Duration(seconds: 2),
),
);
}
static Widget getWidget(String url) {
// 加载网络图片
if (url.startsWith('http')) {
//return CachedNetworkImage(imageUrl: url, fit: BoxFit.cover);
return Image.network(url, fit: BoxFit.cover);
}
// 加载资源文件
if (url.startsWith('assets/images')) {
return Image.asset(url, fit: BoxFit.cover);
}
if (url.startsWith('/storage/emulated')) {
return Image.file(File(url), fit: BoxFit.cover);
}
// 加载失败图片
return Image.asset('assets/images/image_load_error.png', fit: BoxFit.cover);
}
static List<ImageBean> getImageBean(List<File> files) {
List<ImageBean> list = [];
for (int i = 0; i < files.length; i++) {
String url = files[i].path;
list.add(ImageBean(
originPath: url,
middlePath: url,
thumbPath: url,
originalWidth: i == 0 ? 264 : null,
originalHeight: i == 0 ? 258 : null,
));
}
return list;
}
}
屏幕适配(需要先下载flutter_screenutil包)
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ScreenAdapter {
static heigth(num value) {
return ScreenUtil().setHeight(value);
}
static width(num value) {
return ScreenUtil().setWidth(value);
}
static size(num value) {
return ScreenUtil().setSp(value);
}
static getScreenWidth() {
return ScreenUtil().screenWidth; //获取设备的物理宽度
}
static getScreenHigth() {
return ScreenUtil().screenHeight; //获取设备的物理高度
}
}
页面
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:meowfront/models/picture.dart';
import 'package:meowfront/util/PictureUtil.dart';
import 'package:meowfront/util/ScreenAdapter.dart';
import 'package:nine_grid_view/nine_grid_view.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
class PublishPage extends StatefulWidget {
_PublishPageState createState() => _PublishPageState();
}
class _PublishPageState extends State<PublishPage> {
List<ImageBean> _imageList = [];
List<File> _imageFiles = [];
int moveAction = MotionEvent.actionUp;
bool _canDelete = false;
void initState() {
super.initState();
}
selectPictures() async {
final List<AssetEntity>? entitys = await AssetPicker.pickAssets(context,
maxAssets: 9 - _imageFiles.length);
if (entitys == null) return;
//遍历
for (var entity in entitys) {
File? imgFile = await entity.file;
if (imgFile != null) {
setState(() {
_imageFiles.add(imgFile);
_imageList = PictureUtils.getImageBean(_imageFiles);
print('22222' + imgFile.path);
});
}
}
}
_loadAssets(BuildContext context) {
// pick Images.
PictureUtils.showSnackBar(context, "pick Images.");
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: const Text(''),
elevation: 0,
centerTitle: true,
actions: <Widget>[
UnconstrainedBox(
child: Container(
padding: EdgeInsets.only(right: ScreenAdapter.width(20)),
height: ScreenAdapter.heigth(55),
child: ElevatedButton(
child: Text('发布'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white),
// elevation: MaterialStateProperty.all(10),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10))),
),
onPressed: () {
print("圆形按钮2");
}),
),
),
],
),
body: Container(
color: Colors.white,
child: ListView(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(25, 20, 30, 25),
height: ScreenAdapter.heigth(300),
child: TextField(
maxLength: 100,
maxLines: 8,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.zero,
hintText: "分享新鲜事",
hintStyle: TextStyle(color: Colors.black12)
),
),
),
DragSortView(
_imageList,
space: 5,
margin: EdgeInsets.all(20),
padding: EdgeInsets.all(0),
itemBuilder: (BuildContext context, int index) {
ImageBean bean = _imageList[index];
// It is recommended to use a thumbnail picture
return PictureUtils.getWidget(bean.thumbPath!);
},
initBuilder: (BuildContext context) {
return InkWell(
onTap: () {
selectPictures();
},
child: Container(
color: Color(0xFFF0F0F0),
child: Center(
child: Icon(
Icons.add,
),
),
),
);
},
onDragListener: (MotionEvent event, double itemWidth) {
switch (event.action) {
case MotionEvent.actionDown:
moveAction = event.action!;
setState(() {});
break;
case MotionEvent.actionMove:
double x = event.globalX! + itemWidth;
double y = event.globalY! + itemWidth;
double maxX = MediaQuery.of(context).size.width - 1 * 100;
double maxY = MediaQuery.of(context).size.height - 1 * 100;
print('Sky24n maxX: $maxX, maxY: $maxY, x: $x, y: $y');
if (_canDelete && (x < maxX || y < maxY)) {
setState(() {
_canDelete = false;
});
} else if (!_canDelete && x > maxX && y > maxY) {
setState(() {
_canDelete = true;
});
}
break;
case MotionEvent.actionUp:
moveAction = event.action!;
if (_canDelete) {
setState(() {
_canDelete = false;
});
return true;
} else {
setState(() {});
}
break;
}
return false;
},
),
],
),
),
floatingActionButton: moveAction == MotionEvent.actionUp
? null
: FloatingActionButton(
onPressed: () {},
child: Icon(_canDelete ? Icons.delete : Icons.delete_outline),
),
);
}
}![请添加图片描述](https://img-blog.csdnimg.cn/56d1b5d385ab4cda8532462f70a48e4c.jpeg)
效果图
长按图片可以移动或删除