IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter ——图片九宫格,多图片批量上传(图片选择采用官方image_picker实现,批量上传采用dio消息提示) -> 正文阅读

[移动开发]Flutter ——图片九宫格,多图片批量上传(图片选择采用官方image_picker实现,批量上传采用dio消息提示)

需求:实现一个九宫格的效果,要求能够多选照片。
具体描述:
1.实现类似微信九宫格,没图片的时候有一张添加图片,点击该图片可以在相册中选择,当图片未满9个的时候,该图片一直跟在最后,当图片满足9个的时候该添加图片消失。点击右上角X可以移除图片
2.当点击小图的时候能够进行放大的预览,点击大图,预览消失。
3.图片能够进行批量上传,上传的时候进行图片压缩上传

采用的插件
dio: ^4.0.0
fluttertoast: ^8.0.8
image_picker: ^0.8.4+1

#用到的图片放在images文件夹下面
delete.png
addphoto.png


// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs

import 'dart:io';
import 'package:app_flutter/common/global.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

class ImageUploadRoute extends StatefulWidget {
  ImageUploadRoute({Key? key, this.title}) : super(key: key);
  final String? title;
  @override
  _ImageUploadState createState() => _ImageUploadState();
}

class _ImageUploadState extends State<ImageUploadRoute> {
  //编辑文本
  late TextEditingController _controller;

  //图片上传相关
  String  _title="图片上传";
  List<XFile> _imageFileList=List.empty(growable: true);//存放选择的图片
  final ImagePicker _picker = ImagePicker();
  int maxFileCount=9;//最大选择图片数量
  dynamic _pickImageError;
  int _bigImageIndex=0;//选中的需要放大的图片的下标
  bool _bigImageVisibility=false;//是否显示预览大图


  //获取当前展示的图的数量
  int getImageCount() {
    if(_imageFileList.length<maxFileCount){
      return _imageFileList.length+1;
    }else{
      return _imageFileList.length;
    }
  }

  Widget _handlePreview() {
    return _previewImages();
  }
  Widget _previewImages() {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount:3,//每行三个
        childAspectRatio: 1.0,//宽高比1:1
      ),
      itemBuilder: (context,index){
        if(_imageFileList.length<maxFileCount){//没选满
          if(index<_imageFileList.length){//需要展示的图片
            return Stack( //层叠布局 图片上面要有一个删除的框
              alignment: Alignment.center,
              children: [
                Positioned(
                    top:0.0 ,
                    left: 0.0,
                    right: 0.0,
                    bottom: 0.0,
                    child:GestureDetector(
                      child: Image.file(File(_imageFileList[index].path),fit:BoxFit.cover ),
                      onTap:()=>showBigImage(index) ,
                    )
                ),
                Positioned(
                  top:0.0,
                  right: 0.0,
                  width: 20,
                  height: 20,
                  child:GestureDetector(child: SizedBox(child:  Image.asset('images/delete.png'),),
                    onTap:()=>_removeImage(index), ),
                ),

              ],
            );
            //return Image.file(File(_imageFileList[index].path),fit:BoxFit.cover ,) ;
          }else{//显示添加符号
            return GestureDetector( //手势包含添加按钮 实现点击进行选择图片
              child:Image.asset('images/addphoto.png'),
              onTap: ()=>_onImageButtonPressed(//执行打开相册
                ImageSource.gallery,
                context: context,
                imageQuality: 40,//图片压缩
              ),
            );
          }
        }else {//选满了
          return Stack( //层叠布局 图片上面要有一个删除的框
            alignment: Alignment.center,
            children: [
              Positioned(
                top:0.0 ,
                left: 0.0,
                right: 0.0,
                bottom: 0.0,
                child: GestureDetector(
                  child: Image.file(File(_imageFileList[index].path),fit:BoxFit.cover ),
                  onTap:()=>showBigImage(index) ,
                ),
              ),
              Positioned(
                top:0.0,
                right: 0.0,
                width: 20,
                height: 20,
                child:GestureDetector(child: SizedBox(child:  Image.asset('images/delete.png'),),
                  onTap:()=>_removeImage(index), ),
              ),

            ],
          ) ;
        }
      },
      itemCount: getImageCount(),);
  }




  void _onImageButtonPressed(ImageSource source, {BuildContext? context,double? maxHeight,double? maxWidth,int? imageQuality}) async {
    try {
      final pickedFileList = await _picker.pickMultiImage(
        maxWidth: maxWidth,
        maxHeight: maxHeight,
        imageQuality: imageQuality,
      );
      setState(() {
        //pickedFileList.e
        if(_imageFileList.length<maxFileCount){//小于最大数量
          if((_imageFileList.length+(pickedFileList?.length??0))<=maxFileCount){//加上新选中的不超过最大数量
            pickedFileList!.forEach((element) {
              _imageFileList.add(element);
            });
          }else {//否则报错
            Global.showCenterToast("超过可选最大数量!自动移除多余的图片");
            int avaliableCount=maxFileCount-_imageFileList.length;
            for(int i=0;i<avaliableCount;i++){
              _imageFileList.add(pickedFileList![i]);
            }

          }
        }

      });
    } catch (e) {
      setState(() {
        Global.showCenterToast("$_pickImageError");//出现错误的话报错
        _pickImageError = e;
      });
    }

  }

  //移除图片
  void _removeImage(int index){

    setState(() {
      _imageFileList.removeAt(index);
    });
  }

  //通过双击小图的时候获取当前需要放大预览的图的下标
  void showBigImage(int index){
    setState(() {
      _bigImageIndex=index;
      _bigImageVisibility=true;
    });
  }
  //通过大图的双击事件 隐藏大图
  void hiddenBigImage(){
    setState(() {
      _bigImageVisibility=false;
    });
  }

  //展示大图
  Widget? displayBigImage(){
    if(_imageFileList.length>_bigImageIndex){
      return Image.file(File(_imageFileList[_bigImageIndex].path),fit:BoxFit.fill);
    }else{
      return null;
    }
  }



  //图片上传
  _upLoadImage() async {
    List<dynamic> _imgListUpload  = [];
    _imageFileList.forEach((element) {//遍历图片 加入到dio的批量文件里面
      _imgListUpload.add( MultipartFile.fromFileSync(element.path, filename: element.name));
    });
    var formData= FormData.fromMap({
      'files': _imgListUpload,//批量的图片
      'WAREHOUSEID':'TEST', //其他的参数
      'ORDERNO':'HZ00000000001'
    });
    try{
      Dio dio = new Dio();
      var respone = await dio.post<String>("http://192.168.1.21:8080/FlutterService/UploadImages", data: formData);
      if (respone.statusCode == 200) {
        Global.showCenterToast("上传成功!");
      }
    }catch (e) {
      Global.showCenterToast("上传失败!");
    }

  }



  //初始化的时候打开定位相关
  @override
  void initState() {
    super.initState();
    _controller = TextEditingController();

  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }


  //页面的控件布局
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text(_title),),
        body:Stack(
          children: [
            Positioned(//占满屏幕
                top: 0,
                bottom: 0,
                left: 0,
                right: 0,
                child: Column(
                  children: [
                    TextField(
                      maxLines: 10,
                      minLines: 3,
                      controller:_controller,
                      decoration:InputDecoration(
                        border:InputBorder.none ,
                        fillColor:Colors.white ,
                        filled: true,
                        hintText: "签收情况",
                      ),
                    ),
                    SizedBox(
                      height: 400,
                      child: _handlePreview(),
                    ),
                    SizedBox(width: double.infinity,
                      height: 50,
                      child:ElevatedButton(
                        style: ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20)),
                        onPressed: _upLoadImage,
                        child: const Text('确定'),
                      ),
                    ),
                  ],
                )),

            Positioned(
              top: 0,
              bottom: 0,
              left: 0,
              right: 0,
              child:Visibility(
                  visible: _bigImageVisibility,
                  child: GestureDetector(
                    child:displayBigImage(),
                    onTap: hiddenBigImage,
                  )

              ),
            ),
          ],
        )

    );
  }

}





在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:40:21  更:2021-09-24 10:43:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:58:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码