How to reorder a GridView in Flutter?

5.1k views Asked by At

I made a GridView whereby ontap I can show the grid item. by double-tap. I can delete a grid. Now I want to add reorderable property.

Here is my code:

//import 'dart:html';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

int treenumber = 7;

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Garden",
      home: new Home(),
      theme: new ThemeData(primaryColor: Colors.deepOrange),
    );
  }
}

class Home extends StatefulWidget {
  _Homesatate createState() => new _Homesatate();
}

class Tree {
  String name;
  bool visible;

  Tree(this.name, this.visible);
}

class _Homesatate extends State<Home> {
  var trees = [
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true),
    Tree('mango', true),
    Tree('apple', true)
  ];
  @override
  Widget build(BuildContext context) {
    var gridview = new GridView.builder(
      itemCount: trees.length,
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: treenumber),
      itemBuilder: (BuildContext context, int index) {
        return new GestureDetector(
          child: new Visibility(
            visible: trees[index].visible,
            child: new Card(
              elevation: 2.0,
              child: new Container(
                alignment: Alignment.center,
                margin: new EdgeInsets.all(2.0),
                child: new Text(trees[index].name),
              ),
            ),
          ),
          onTap: () {
            showDialog(
                builder: (context) => new CupertinoAlertDialog(
                      title: new Column(
                        children: <Widget>[
                          new Text("Tree"),
                          new Icon(
                            Icons.favorite,
                            color: Colors.red,
                          )
                        ],
                      ),
                      content: new Text(trees[index].name),
                      actions: <Widget>[
                        new FlatButton(
                            onPressed: () {
                              Navigator.of(context).pop();
                            },
                            child: new Text("Ok"))
                      ],
                    ),
                barrierDismissible: false,
                context: context);
          },
          onDoubleTap: () => setState(() {
            trees[index].visible = !trees[index].visible;
          }),
        );
      },
    );

    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Garden"),
      ),
      body: gridview,
    );
  }
}

void main(List<String> args) {
  runApp(MyApp());
}

By long-press a grid I can replace it anywhere. There will be reordered other grids.

I tried several methods. But, that doesn't include my ontap and doubletap features.

How can I keep those properties and also want to add a reorderable grid?

1

There are 1 answers

2
Jim On

Are you looking for this, drag_and_drop_gridview

 _animals = ['cat','dog','kitten','puppy']
 
DragAndDropGridView(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        childAspectRatio: 3 / 4.5,
    ),
    padding: EdgeInsets.all(20),
    itemBuilder: (context, index) => Card(
        elevation: 2,
        child: Text(_animals[index]),
        ),
    ),
    itemCount: _animals.length,
    onWillAccept: (oldIndex, newIndex) {
        // Implement you own logic

        // Example reject the reorder if the moving item's destination value is cat"
        if (_animals[newIndex] == "cat"){
            return false;
        }
        return true, // If you want to accept the child return true or else return false
    },
    onReorder: (oldIndex, newIndex) {
        _temp = _animals[newIndex];
        _animals[newIndex] = _animals[oldIndex];
        _animals[oldIndex] = _temp;
        setState(() {});
    },
)