【问题标题】:GridView images drag and drop flutterGridView 图像拖放颤动
【发布时间】:2021-06-24 19:57:47
【问题描述】:

我有一个使用 Flutter 框架的代码,它允许在上传到 firebase 之前选择多个图像并查看图像。 选择图像后,我希望能够拖放这些图像,以便重新排列这些图像,并在以后按照用户选择的顺序保存它们。

我尝试实现这种拖放,但我看到的所有示例都是针对 ListView 的,而我的情况并非如此 :(

这是我的代码:

import 'package:drag_and_drop_gridview/devdrag.dart';
import 'package:drag_and_drop_gridview/drag.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
import 'package:path/path.dart' as Path;

import 'package:flutter/services.dart';


class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {


  bool uploading = false;
  double val = 0;
  CollectionReference imgRef;
  firebase_storage.Reference ref;

  List<File> _image = [];
  final picker = ImagePicker();
  
  int variableSet = 0, variableSetHeader = 0;
  ScrollController _scrollController;
  double width;
  double height;
  
  @override
  Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Horizontal DragAndDropGridView'),
          actions: [
            // ignore: deprecated_member_use
            FlatButton(
                onPressed: () {
                  setState(() {
                    uploading = true;
                  });
                  uploadFile().whenComplete(() => Navigator.of(context).pop());
                },

                child: Text(
                  'upload',
                  style: TextStyle(color: Colors.white),
                )),
          ],

        ),




        body: Stack(
          children: [
          Container(
              padding: EdgeInsets.all(4),
             child: DragAndDropGridView.horizontal(
              controller: _scrollController,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 5,
                childAspectRatio: 3 / 4.5,
              ),
              padding: EdgeInsets.all(20),
              itemBuilder: (context, index) => Container(
                padding: EdgeInsets.all(4),
                child: GridView.builder(
                    itemCount: _image.length + 1,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 3),
                    itemBuilder: (context, index) {
                      return index == 0
                          ? Center(
                        child: IconButton(
                            icon: Icon(Icons.add),
                            onPressed: () =>
                            !uploading ? chooseImage() : null),
                      )
                          : Container(
                        margin: EdgeInsets.all(3),
                        decoration: BoxDecoration(
                            image: DecorationImage(
                              image: FileImage(_image[index - 1]),
                              fit: BoxFit.cover,
                            )
                        ),
                      );
                    }
                ),
              ),
              itemCount: _image.length,
              onWillAccept: (oldIndex, newIndex) => true,
              onReorder: (oldIndex, newIndex) {
                int indexOfFirstItem = _image.indexOf(_image[oldIndex]);
                int indexOfSecondItem = _image.indexOf(_image[newIndex]);

                if (indexOfFirstItem > indexOfSecondItem) {
                  for (int i = _image.indexOf(_image[oldIndex]);
                  i > _image.indexOf(_image[newIndex]);
                  i--) {
                    var tmp = _image[i - 1];
                    _image[i - 1] = _image[i];
                    _image[i] = tmp;
                  }
                } else {
                  for (int i = _image.indexOf(_image[oldIndex]);
                  i < _image.indexOf(_image[newIndex]);
                  i++) {
                    var tmp = _image[i + 1];
                    _image[i + 1] = _image[i];
                    _image[i] = tmp;
                  }
                }
                setState(() {});
              },
            ),
          ),


            uploading
                ? Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      child: Text(
                        'uploading...',
                        style: TextStyle(fontSize: 20),
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),

                    CircularProgressIndicator(
                      value: val,
                      valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
                    ),

                  ],
                )
            )
                : Container(),
          ],
        )
    );
  }


  chooseImage() async {
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
    setState(() {
      _image.add(File(pickedFile?.path));
    });
    if (pickedFile.path == null) retrieveLostData();
  }

  Future<void> retrieveLostData() async {
    final LostData response = await picker.getLostData();
    if (response.isEmpty) {
      return;
    }
    if (response.file != null) {
      setState(() {
        _image.add(File(response.file.path));
      });
    } else {
      print(response.file);
    }
  }

  Future uploadFile() async {
    int i = 1;
    var firebaseUser =  FirebaseAuth.instance.currentUser.email;
    for (var img in _image) {
      setState(() {
        val = i / _image.length;
      });
      ref = firebase_storage.FirebaseStorage.instance
          .ref()
          .child('${firebaseUser}/Livres/${Path.basename(img.path)}');
      await ref.putFile(img).whenComplete(() async {
        await ref.getDownloadURL().then((value) {
          imgRef.add({'url': value});
          i++;
        });
      });
    }
  }

  @override
  void initState() {
    var firebaseUser =  FirebaseAuth.instance.currentUser.email;

    super.initState();
    imgRef = FirebaseFirestore.instance.collection(firebaseUser);
  }
}

【问题讨论】:

    标签: flutter dart flutter-layout flutter-dependencies flutter-animation


    【解决方案1】:

    您可以使用 reorderable_grid_view 包。它是 null 安全且易于使用的。

    reorderable_grid_view

    它的 ReorderableGridView.count 方法具有与 GridView.count 相同的属性,并具有一些额外的属性,例如 reorder 以拖放/重新排序 gridview。

    以下 youtube 视频将帮助您了解有关 gridview 拖放的更多详细信息。

    Flutter - Drag & drop items in Gridview

    【讨论】:

      【解决方案2】:

      使用 Draggable 小部件或使用此插件draggable gridView

      【讨论】:

      • 我也试过了。即使我的代码没有任何错误,它也不起作用。也许是因为我除了图像之外还有什么。我使用可拖动小部件更新了我的代码
      • 有没有使用children的key属性,拖拽后有没有更新UI?
      • 很遗憾没有,我刚刚检查了“关键属性”的使用情况,实际上这似乎可以解决问题。但由于我从未使用过它,我不知道如何将它放在上面的代码中:(
      • Key 用于与其他小部件进行识别,因此 Key("parameter") 参数应与其他 key 的参数不同
      • 是否有一个 null 安全的替代方案?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-14
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多