美文网首页Flutter
flutter实现多图选择+常用做法

flutter实现多图选择+常用做法

作者: _诸葛青 | 来源:发表于2021-03-30 11:17 被阅读0次

    先看效果。


    1617074157230.gif
    注:可以用其他多图片选择插件,列表插件可以不用。
      #图片选择
      wechat_assets_picker: ^4.2.1
      #列表
      flutter_staggered_grid_view: ^0.3.2
    

    Android配置

        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
    361617070061_.pic_hd.jpg

    完整代码

    import 'dart:io';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
    import 'package:wechat_assets_picker/wechat_assets_picker.dart';
    
    class PhotoTool extends StatefulWidget {
     @required final int imageCount;//最多几张
     @required  final int lineCount;//一行几个
     //注:最好把图片和文字这些都拿出来,方便更改,这里就不搞了
      const PhotoTool({Key key, this.imageCount,this.lineCount});
      @override
      _PhotoToolState createState() => _PhotoToolState();
    }
    
    class _PhotoToolState extends State<PhotoTool> {
      List<AssetEntity> _imageFiles = [];
      @override
      Widget build(BuildContext context) {
        return Container(
          width: double.infinity,
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                RichText(
                  text: TextSpan(
                    text: '说明:',
                    style: Theme.of(context).textTheme.subtitle2,
                    children: [
                      TextSpan(
                        text: '(说明:上传图片,最多${widget.imageCount}张)',
                        style: Theme.of(context)
                            .textTheme
                            .bodyText2
                            .copyWith(color: Colors.grey),
                      ),
                    ],
                  ),
                ),
                SizedBox(height: 16.0),
                StaggeredGridView.countBuilder(
                  shrinkWrap: true,
                  crossAxisCount: widget.lineCount,
                  itemCount: _imageFiles.length == widget.imageCount
                      ? _imageFiles.length
                      : _imageFiles.length + 1,
                  physics: NeverScrollableScrollPhysics(),
                  itemBuilder: (BuildContext context, int index) {
                    if (_imageFiles.length < widget.imageCount && index == 0) {
                      return InkWell(
                        onTap: () => _onPickImage(),
                        child: Container(
                          padding: EdgeInsets.all(5),
                          child: Container(
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(5.0),
                              color: Color(0xFFF6F7F8),
                            ),
                            child: Center(
                              child: Icon(
                                Icons.add,
                                color: Color(0xFFB4B4B4),
                                size: 40,
                              ),
                            ),
                          ),
                        ),
                      );
                    } else {
                      return Stack(
                        children: [
                          Container(
                            padding: EdgeInsets.all(5),
                            child: InkWell(
                              child: FutureBuilder<File>(
                                future: _imageFiles[
                                _imageFiles.length < widget.imageCount
                                    ? index - 1
                                    : index]
                                    .file,
                                builder: (context, snapshot) {
                                  return snapshot.connectionState ==
                                      ConnectionState.done
                                      ? Container(
                                    decoration: BoxDecoration(
                                      shape: BoxShape.rectangle,
                                      borderRadius:
                                      BorderRadius.circular(6.0),
                                      image: DecorationImage(
                                        image: FileImage(snapshot.data),
                                        fit: BoxFit.cover,
                                      ),
                                    ),
                                  )
                                      : Container(
                                    decoration: BoxDecoration(
                                      shape: BoxShape.rectangle,
                                      borderRadius:
                                      BorderRadius.circular(6.0),
                                      color: Color(0xFFF6F7F8),
                                    ),
                                    child: Center(
                                      child: CupertinoActivityIndicator(),
                                    ),
                                  );
                                },
                              ),
                            ),
                          ),
                          InkWell(
                            onTap: () => _deleteImage(
                                _imageFiles.length < widget.imageCount
                                    ? index - 1
                                    : index),
                            child: Container(
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(99.0),
                                color: Colors.red,
                              ),
                              padding: EdgeInsets.all(2.0),
                              child: Icon(
                                Icons.close,
                                size: 20.0,
                                color: Colors.white,
                              ),
                            ),
                          ),
                        ],
                      );
                    }
                  },
                  staggeredTileBuilder: (int index) =>
                  new StaggeredTile.count(1, 1),
                  mainAxisSpacing: 4.0,
                  crossAxisSpacing: 4.0,
                ),
              ],
            ),
          ),
        );
      }
      /// 选择图片
      _onPickImage() async {
        List<AssetEntity> assets = await AssetPicker.pickAssets(
          context,
          maxAssets: widget.imageCount - _imageFiles.length,
          themeColor: Theme.of(context).primaryColor,
          requestType: RequestType.image,
        );
        if (assets == null || assets.length <= 0) return;
        setState(() {
          _imageFiles.addAll(assets);
        });
      }
      /// 删除图片
      _deleteImage(int index) {
        if (_imageFiles == null || _imageFiles.length <= index) return;
        setState(() {
          _imageFiles.removeAt(index);
        });
      }
    }
    

    使用

        return Scaffold(
          appBar: AppBar(
            // Here we take the value from the MyHomePage object that was created by
            // the App.build method, and use it to set our appbar title.
            title: Text(widget.title),
          ),
          body:PhotoTool(
            imageCount: 9,
            lineCount: 3,
          )
    

    其他说明(可能用到):正常我们对接接口都是给接口传base64.格式

    ///AssetEntity转Fil   .file(插件自带)
    ///file转base64
     //通过图片路径将图片转换成Base64字符串
      Future image2Base64(String path) async {
        File file = new File(path);
        List<int> imageBytes = await file.readAsBytes();
        return base64Encode(imageBytes);
      }
    ///基本用法
          _imageFiles.forEach((item) {
              item.file.then((value)async{
              String _base64ImageStr =  await CommonUtils.getInstance().image2Base64(value.path);
            });
          });
    

    相关文章

      网友评论

        本文标题:flutter实现多图选择+常用做法

        本文链接:https://www.haomeiwen.com/subject/comwhltx.html