Hello I am new to flutter and am working on a project and am creating a form builder in flutter. To do this we are using draggable items such as text input fields. A draggable item is placed in the drag target and is accepted just fine. However, the issue is that when we go to click the item in order to input text the item is immediately removed. In the image below the blue is the drag target and the white underneath is the draggable items. As you can see the text input is added correctly, it is when I try and add input to the field that the item is immediately removed before I can even start typing.
I have stepped through this on the VS code debugger and when I click to input text it returns me to this snippet right before the item is removed:
Container(
width: MediaQuery.of(context).size.width / 4,
child: Draggable<Widget>(
child: ListTile(
title: Text('Add Text Response'),
trailing: Icon(Icons.text_fields),
),
data: new TextInputItem(),
feedback: Text('Text'),
),
Here is the relevant code:
class CreateProject extends StatefulWidget {
@override
_CreateProjectState createState() => _CreateProjectState();
}
class _CreateProjectState extends State<CreateProject> {
@override
Widget build(BuildContext context) {
List<Widget> acceptData = [];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Create New Project"),
),
body: Padding(
padding: EdgeInsets.all(10),
child: Container(
child: Column(
children: <Widget>[
Expanded(
child: DragTarget(
onWillAccept: (Widget addItem) {
print('checking if will accept item');
print(addItem);
if (addItem == null) {
return false;
}
return true;
},
onAccept: (Widget addItem) {
print('accepting an item');
acceptData.add(addItem);
print(acceptData);
},
builder: (context, List<dynamic> candidateData,
List<dynamic> rejectedData) {
return Container(
height: MediaQuery.of(context).size.height,
color: Colors.lightBlue[50],
child: acceptData.isEmpty
? Center(
child: Text('Add Form Fields Here'),
)
: Column(children: acceptData),
);
},
),
),
Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 4,
child: Draggable<Widget>(
child: ListTile(
title: Text('Add Text Response'),
trailing: Icon(Icons.text_fields),
),
data: new TextInputItem(),
feedback: Text('Text'),
),
),
],
),
Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 4,
child: Draggable<Widget>(
child: ListTile(
title: Text('Add User Location'),
trailing: Icon(Icons.location_on),
),
//child: Text('User Location'),
data: new UserLocation(),
feedback: Text('Text'),
),
),
],
),
Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 4,
child: Draggable<Widget>(
data: new MultipleChoice(),
feedback: Text('Mult choice'),
child: ListTile(
title: Text('Add Multiple choice'),
trailing: Icon(Icons.add_box),
),
),
),
],
),
],
),
),
),
),
);
}
}
class TextInputItem extends StatefulWidget {
@override
_TextInputItemState createState() => _TextInputItemState();
}
class _TextInputItemState extends State<TextInputItem> {
final controller = new TextEditingController();
@override
Widget build(BuildContext context) {
return Container(
margin: new EdgeInsets.all(8.0),
child: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Text Input Prompt',
),
),
);
}
}
Here is an example image:
Because you declare acceptData
in Widget build
When Widget
rebuild acceptData
become null
again
Please change from
@override
Widget build(BuildContext context) {
List<Widget> acceptData = [];
To
List<Widget> acceptData = [];
@override
Widget build(BuildContext context) {