Marc Hampson
Marc Hampson

Reputation: 267

Flutter Drag and Drop ListView hasSize is not true

Can someone fire up a quick flutter project and replace main.dart with the following and see what I'm doing wrong? I'm trying to get drag and drop working in ListView.

I'm not even sure this is the right approach so if not, please let me know.

The error I'm getting now is:

Another exception was thrown: 'package:flutter/src/rendering/box.dart': Failed assertion: line 1446 pos 12: 'hasSize': is not true.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'Basic List';

    var tile1 = new Material(child:
       new ListTile(
          leading: new Icon(Icons.photo),
          title: new Text('Row 1'),
          trailing: new Icon(Icons.reorder),

    ));


    var tile2 = new Material(
        child:
          new ListTile(
            leading: new Icon(Icons.photo),
            title: new Text('Row 2'),
            trailing: new Icon(Icons.reorder),
    ));


    return new MaterialApp(
      title: title,
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text(title),
        ),
        body:
        new GestureDetector(
          onVerticalDragStart: startDrag,
          onVerticalDragEnd: endDrag,
          child: new ListView(
            shrinkWrap: true,
            children: [
                  new Flex (

                    children: <Widget>[
                      new Flexible(
                        child: new Draggable(child: tile1, feedback: 
tile1),
                      ),
                      new Flexible(
                        child: new Draggable(child: tile2, feedback: 
tile2),
                      ),
                    ],
                    direction: Axis.vertical,
                    mainAxisAlignment: MainAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                  ),
            ],
          ),
        ),
      ),
    );
  }

  void startDrag(DragStartDetails event) {}

  void endDrag(DragEndDetails event) {}
}

Thanks

Upvotes: 2

Views: 11071

Answers (1)

Marc Hampson
Marc Hampson

Reputation: 267

With a little help along the way from @Darky to resolve the issue hasSize issue, here's the finished sortable ListView example:

https://github.com/marchampson/FluterSortableListView

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {

  List<String> rows = new List<String>()
    ..add('Row 1')
    ..add('Row 2')
    ..add('Row 3')
    ..add('Row 4');

  void _handleAccept(int data, int index) {
    setState(() {
      String imageToMove = rows[data];
      rows.removeAt(data);
      rows.insert(index, imageToMove);
    });
  }

  @override
  Widget build(BuildContext context) {

    final title = 'Sortable ListView';

    return new MaterialApp(
      title: title,
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text(title),
        ),
        body:
        new LayoutBuilder(builder: (context, constraint) {
          return new ListView.builder(
            itemCount: rows.length,
            addRepaintBoundaries: true,
            itemBuilder: (context, index) {
              return new LongPressDraggable(
                key: new ObjectKey(index),
                data: index,
                child: new DragTarget<int>(
                  onAccept: (int data) {
                    _handleAccept(data, index);
                  },
                  builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
                    return new Card(
                        child: new Column(
                          children: <Widget>[
                            new ListTile(
                                leading: new Icon(Icons.photo),
                                title: new Text(rows[index])
                            ),
                          ],
                        )
                    );
                  },
                  onLeave: (int data) {
                    // Debug
                    print('$data is Leaving row $index');
                  },
                  onWillAccept: (int data) {
                    // Debug
                    print('$index will accept row $data');

                    return true;
                  },
                ),
                onDragStarted: () {
                  Scaffold.of(context).showSnackBar(new SnackBar (
                    content: new Text("Drag the row onto another row to change places"),
                  ));

                },
                onDragCompleted: () {
                  print("Finished");
                },
                feedback: new SizedBox(
                    width: constraint.maxWidth,
                     child: new Card (
                      child: new Column(
                        children: <Widget>[
                          new ListTile(
                            leading: new Icon(Icons.photo),
                            title: new Text(rows[index]),
                            trailing: new Icon(Icons.reorder),
                          ),
                        ],
                      ),
                      elevation: 18.0,
                    )
                ),
                childWhenDragging: new Container(),
              );
            },
          );
        }),
      ),
    );
  }
}

Upvotes: 2

Related Questions