【发布时间】:2019-06-29 11:02:02
【问题描述】:
如何在屏幕上移动我的容器或任何其他小部件并掉落在某些位置?
我发现了颤振小部件Draggable 和DragTarget。如何使用它们来实现拖放?
【问题讨论】:
标签: flutter
如何在屏幕上移动我的容器或任何其他小部件并掉落在某些位置?
我发现了颤振小部件Draggable 和DragTarget。如何使用它们来实现拖放?
【问题讨论】:
标签: flutter
Draggable 和DragTarget 允许我们在屏幕上拖动一个小部件。
Draggable 小部件可以移动到任何其他小部件,而DragTarget 充当Draggable 小部件的接收器或放置位置。
找到下面的代码示例,我使用它实现了一个简单的奇偶游戏
该死,我是游戏开发者◕‿↼
import 'package:flutter/material.dart';
import 'dart:math';
class OddOrEven extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _OddOrEvenState();
}
}
class _OddOrEvenState extends State<OddOrEven> {
bool accepted = false;
Color dotColor = Colors.blue;
GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey();
int val = 0;
int score = 0;
@override
Widget build(BuildContext context) {
// assign a random number to value which will be used as the box value
val = Random().nextInt(100);
return Scaffold(
key: scaffoldKey,
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// just a score and mock player name indicator
Padding(
padding: EdgeInsets.all(16.0),
child: Center(
child: Center(
child: Chip(
avatar: CircleAvatar(
backgroundColor: Colors.teal,
child: Text(
score.toString(),
style: TextStyle(color: Colors.white),
),
),
label: Text(
'Player Alpha',
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontStyle: FontStyle.italic),
),
),
),
),
),
// here comes our draggable.
// it holds data which is our random number
// the child of the draggable is a container reactangural in shape and
//
Draggable(
data: val,
child: Container(
width: 100.0,
height: 100.0,
child: Center(
child: Text(
val.toString(),
style: TextStyle(color: Colors.white, fontSize: 22.0),
),
),
color: Colors.pink,
),
// This will be displayed when the widget is being dragged
feedback: Container(
width: 100.0,
height: 100.0,
child: Center(
child: Text(
val.toString(),
style: TextStyle(color: Colors.white, fontSize: 22.0),
),
),
color: Colors.pink,
),
// You can also specify 'childWhenDragging' option to draw
// the original widget changes at the time of drag.
),
// and here this row holds our two DragTargets.
// One for odd numbers and the other for even numbers.
//
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 100.0,
height: 100.0,
color: Colors.green,
// Even holder DragTarget
//
child: DragTarget(
builder: (context, List<int> candidateData, rejectedData) {
print(candidateData);
return Center(
child: Text(
"Even",
style: TextStyle(color: Colors.white, fontSize: 22.0),
));
},
// On will accept gets called just before it accepts the drag source.
// if needed, we can reject the data here. But we are not doing that as this is a GAME !!! :)
onWillAccept: (data) {
print("Will accpt");
return true; //return false to reject it
},
// On accepting the data by the DragTarget we simply check whether the data is odd or even and accept based on that and increment the counter and rebuild the widget tree for a new random number at the source.
onAccept: (data) {
print("On accpt");
if (data % 2 == 0) {
setState(() {
score++;
});
// How did you manage to score 3 points?
// Congrats. You won the game.
if (score >= 3) {
showDialog(
context: context,
builder: (BuildContext context) {
return new AlertDialog(
title: Text("Congrats!!"),
content: Text("No-brainer...?"),
actions: <Widget>[
FlatButton(
child: Text("Ok."),
onPressed: () {
Navigator.of(context).pop();
setState(() {
score = 0;
});
},
)
],
);
});
}
} else {
setState(() {});
}
},
),
),
// And here is the Odd-holder
Container(
width: 100.0,
height: 100.0,
color: Colors.deepPurple,
child: DragTarget(
builder: (context, List<int> candidateData, rejectedData) {
return Center(
child: Text(
"Odd",
style: TextStyle(color: Colors.white, fontSize: 22.0),
));
},
onWillAccept: (data) {
return true;
},
onAccept: (data) {
if (data % 2 != 0) {
setState(() {
score++;
});
if (score >= 10) {
showDialog(
context: context,
builder: (BuildContext context) {
return new AlertDialog(
title: Text("Congrats!!"),
content: Text("No-brainer...?"),
actions: <Widget>[
FlatButton(
child: Text("Thanks"),
onPressed: () {
Navigator.of(context).pop();
setState(() {
score = 0;
});
},
)
],
);
});
}
} else {
setState(() {});
}
},
),
)
],
)
],
),
),
);
}
}
【讨论】:
如果您需要放置在非固定位置(无需 DragTarget 的 Draggable),这也可以通过 Stack()/Positioned() 使用渲染框大小来实现,根据 How to move element anywhere inside parent container with drag and drop in Flutter?
【讨论】: