Je souhaite créer un widget dans lequel vous pouvez ajouter plusieurs widgets de tailles différentes et modifier leur position à l'aide de la technique du glisser-déposer. Quelque chose comme une vue en grille avec glisser-déposer où vous pouvez modifier la position horizontalement et verticalement. Pendant que vous faites glisser le widget sélectionné, d'autres widgets se déplacent pour lui laisser de la place.
Quelqu'un a-t-il une idée par où commencer ou existe-t-il déjà des exemples mettant en œuvre ce que je recherche?
Vous pouvez également essayer celui-ci plus facile (il n'inclut pas de commentaires)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold(body: HomePage()));
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Offset offset = Offset.zero;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: offset.dx,
top: offset.dy,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
offset = Offset(offset.dx + details.delta.dx, offset.dy + details.delta.dy);
});
},
child: Container(width: 100, height: 100, color: Colors.blue),
),
),
],
);
}
}
Bien que cela puisse ne pas répondre à votre question, mais aux personnes qui recherchent un simple widget glisser-déposer, voici l'exemple.
Voir ma 2ème réponse pour plus simple
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Drag app"),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomePageState();
}
}
class _HomePageState extends State<HomePage> {
double width = 100.0, height = 100.0;
Offset position ;
@override
void initState() {
super.initState();
position = Offset(0.0, height - 20);
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: position.dx,
top: position.dy - height + 20,
child: Draggable(
child: Container(
width: width,
height: height,
color: Colors.blue,
child: Center(child: Text("Drag", style: Theme.of(context).textTheme.headline,),),
),
feedback: Container(
child: Center(
child: Text("Drag", style: Theme.of(context).textTheme.headline,),),
color: Colors.blue[300],
width: width,
height: height,
),
onDraggableCanceled: (Velocity velocity, Offset offset){
setState(() => position = offset);
},
),
),
],
);
}
}
Voici un exemple de texte déplaçable
class DraggableText extends StatefulWidget {
final Offset initialOffset;
final String text;
DraggableText(this.text, this.initialOffset);
@override
_DraggableTextState createState() => new _DraggableTextState();
}
class _DraggableTextState extends State<DraggableText> {
Offset position = new Offset(0.0, 0.0);
@override
void initState() {
super.initState();
position = widget.initialOffset;
}
@override
Widget build(BuildContext context) {
final item = new LabelBox(size: new Size.square(100.0), label: widget.text);
final avatar = new LabelBox(
size: new Size.square(150.0), label: widget.text, opacity: 0.4);
final draggable = new Draggable(
data: widget.text,
feedback: avatar,
child: item,
childWhenDragging: new Opacity(opacity: 0.0, child: item),
onDraggableCanceled: (velocity, offset) {
print('_DragBoxState.build -> offset ${offset}');
setState(() => position = offset);
});
return new Positioned(
left: position.dx, top: position.dy, child: draggable);
}
}
Vous pouvez consulter des exemples complets et des exemples plus avancés ici https://github.com/rxlabz/flutter_dropcity
Je ne peux pas écrire de commentaires à cause de ma réputation mais je voulais répondre à cette question à partir des commentaires de la réponse de CopsOnRoad:
Je ne veux pas afficher la vue des commentaires au lieu de cela, je veux faire glisser vue originale. C'est possible?
Si certains le recherchent aussi, vous pouvez utiliser: childWhenDragging: Container () . Vous faites toujours glisser le commentaire, mais l'enfant d'origine sera masqué.
...
child: Draggable(
child: Container(
width: width,
height: height,
color: Colors.blue,
child: Center(child: Text("Drag", style: Theme.of(context).textTheme.headline,),),
),
feedback: Container(
child: Center(
child: Text("Drag", style: Theme.of(context).textTheme.headline,),),
color: Colors.blue[300],
width: width,
height: height,
),
childWhenDragging: Container(), // <-- so it looks like the original view is beeing dragged
onDraggableCanceled: (Velocity velocity, Offset offset){
setState(() => position = offset);
},
),
...