1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > flutter仿微信朋友圈发布页面图片上传及九宫格展示

flutter仿微信朋友圈发布页面图片上传及九宫格展示

时间:2023-08-10 22:36:00

相关推荐

flutter仿微信朋友圈发布页面图片上传及九宫格展示

使用到的包

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 work(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 {@override_PublishPageState createState() => _PublishPageState();}class _PublishPageState extends State<PublishPage> {List<ImageBean> _imageList = [];List<File> _imageFiles = [];int moveAction = MotionEvent.actionUp;bool _canDelete = false;@overridevoid 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.");}@overrideWidget 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 picturereturn 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-/56d1b5d385ab4cda8532462f70a48e4c.jpeg)

效果图

长按图片可以移动或删除

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。