web-dev-qa-db-fra.com

Liste de glisser-déposer triable Flutter

Je commence donc à apprendre Flutter et je voudrais utiliser une liste de glisser-déposer de conception de matériaux, tout comme celle vue sur le site Web des directives sur les matériaux.

https://storage.googleapis.com/spec-Host-backup/mio-design%2Fassets%2F1dtprsH4jZ2nOnjBCJeJXd7n4U-jmWyas%2F03-list-reorder.mp4

Toutes les bibliothèques que j'ai essayées jusqu'à présent ressemblent à des ordures par rapport à cela. Existe-t-il une bonne bibliothèque pour cela qui me manque ou un widget Flutter natif?

8
Jared

Vérifiez knopp/flutter_reorderable_list . Il accomplit exactement cela. C'est vraiment fluide et il n'y a aucun problème de performance, étant capable de gérer des milliers d'éléments.

Cependant, sa mise en œuvre n'est pas aussi simple que les widgets de flottement habituels.

Si vous rencontrez des difficultés, je vous recommande d'utiliser un widget que j'ai créé pour porter flutter/ReorderableListViews au knopp/ReorderableList.

Ce widget le rend vraiment facile à utiliser, mais il n'offre pas la même flexibilité, et comme il fonctionne avec un childrenList, il n'est pas aussi évolutif que l'original.

Voici le code pour ReorderableListSimple et voici la démo .

4
Feu

Flutter lui-même fournit un (Material) ReorderableListView class .

7
jamesdlin

enter image description here

Vous pouvez utiliser le widget de flottement natif, ReorderableListView pour y parvenir, voici l'exemple de le faire.

List<String> _list = ["Apple", "Ball", "Cat", "Dog", "Elephant"];

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(),
    body: ReorderableListView(
      children: _list.map((item) => ListTile(key: Key("${item}"), title: Text("${item}"), trailing: Icon(Icons.menu),)).toList(),
      onReorder: (int start, int current) {
        // dragging from top to bottom
        if (start < current) {
          int end = current - 1;
          String startItem = _list[start];
          int i = 0;
          int local = start;
          do {
            _list[local] = _list[++local];
            i++;
          } while (i < end - start);
          _list[end] = startItem;
        }
        // dragging from bottom to top
        else if (start > current) {
          String startItem = _list[start];
          for (int i = start; i > current; i--) {
            _list[i] = _list[i - 1];
          }
          _list[current] = startItem;
        }
        setState(() {});
      },
    ),
  );
}
5
CopsOnRoad

J'ai essayé flutter_reorderable_list et dragable_flutter_list mais aucun d'entre eux n'a fonctionné correctement - il y a eu des artefacts indésirables pendant le glissement. J'ai donc essayé de faire ma propre solution:

ListView.builder(
  itemBuilder: (context, index) => buildRow(index),
  itemCount: trackList.length,
),

Widget buildRow(int index) {
  final track = trackList[index];
  ListTile tile = ListTile(
    title: Text('${track.getName()}'),
  );
  Draggable draggable = LongPressDraggable<Track>(
    data: track,
    axis: Axis.vertical,
    maxSimultaneousDrags: 1,
    child: tile,
    childWhenDragging: Opacity(
      opacity: 0.5,
      child: tile,
    ),
    feedback: Material(
      child: ConstrainedBox(
        constraints:
            BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
        child: tile,
      ),
      elevation: 4.0,
    ),
  );

  return DragTarget<Track>(
    onWillAccept: (track) {
      return trackList.indexOf(track) != index;
    },
    onAccept: (track) {
      setState(() {
        int currentIndex = trackList.indexOf(track);
        trackList.remove(track);
        trackList.insert(currentIndex > index ? index : index - 1, track);
      });
    },
    builder: (BuildContext context, List<Track> candidateData,
        List<dynamic> rejectedData) {
      return Column(
        children: <Widget>[
          AnimatedSize(
            duration: Duration(milliseconds: 100),
            vsync: this,
            child: candidateData.isEmpty
                ? Container()
                : Opacity(
                    opacity: 0.0,
                    child: tile,
                  ),
          ),
          Card(
            child: candidateData.isEmpty ? draggable : tile,
          )
        ],
      );
    },
  );
}

Je suppose que ce n'est pas la meilleure solution, et je vais peut-être la changer davantage, mais pour l'instant cela fonctionne assez bien

4
Andrey Turkovsky

L'équipe Flutter a introduit le widget ReorderableListView .

ReorderableListView(
      children: <Widget>[
        for (var item in appState.menuButtons) 
        Text('data')              

      ],
    )
0
Benjith Kizhisseri