Для этого сценария вам нужно будет использовать обратный вызов. Из-за области видимости переменных вы не можете напрямую удалить переменную из noteString в InputWidget () из-за области видимости, однако она ДОЛЖНА быть инициирована InputWidget, поскольку информация об индексе содержится в этом виджете и должна использоваться удалить элементы из списка noteString, а также удалить InputWidget из дочернего списка. Следовательно, это время обратного вызова.
Обратные вызовы работают следующим образом: 1. определяют переменную, которая получит функцию в дочернем элементе.
final Function(int) onDelete;
2. Вызовите функцию у потомка и передайте нужную переменную:
onLongPress: () {
widget.onDelete(widget.index);
},
3. Определите в родительской функции, которую вы хотите использовать в РОДИТЕЛЕ, а затем передайте ее ребенку:
Function(int) onDeleteVar = (int val) {
setState(
() => {
noteString.removeAt(val),
count--,
children.removeAt(val),
},
);
};
children = List.generate(
count,
(int i) => new InputWidget(i,
noteRec: noteString[i],
noteString: noteString,
count: count,
onDelete: onDeleteVar));
Вот дартпад, чтобы увидеть его в действии: http://dartpad.dev/a25e9c402a90fefc778bcfac27aee242
А вот код:
import 'dart:core';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
MyHomePageState createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
int count = 0;
TextEditingController noteSend = TextEditingController();
List<String> noteString = [];
@override
Widget build(BuildContext context) {
List<Widget> children;
Function(int) onDeleteVar = (int val) {
setState(
() => {
print("noteStringBefore: $noteString"),
print('childrenBefore: $children'),
print(val),
noteString.removeAt(val),
count--,
children.removeAt(val),
print("noteStringAfter: $noteString"),
print('childrenAfter $children'),
},
);
};
children = List.generate(
count,
(int i) => new InputWidget(i,
noteRec: noteString[i],
noteString: noteString,
count: count,
onDelete: onDeleteVar));
return new Scaffold(
appBar: new AppBar(title: new Text('some title')),
body: Column(
children: <Widget>[
Container(
child: TextField(
controller: noteSend,
),
color: Colors.lightBlueAccent,
width: 150,
height: 50,
),
Expanded(
child: ListView(
children: children,
scrollDirection: Axis.vertical,
),
),
],
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
onPressed: () {
setState(() {
noteString.insert(
noteString.length,
noteSend.text,
);
count = count + 1;
});
},
));
}
}
class InputWidget extends StatefulWidget {
final int index;
final String noteRec;
final List<String> noteString;
final int count;
final Function(int) onDelete;
InputWidget(this.index,
{Key key, this.noteRec, this.noteString, this.count, this.onDelete})
: super(key: key);
@override
_InputWidgetState createState() => _InputWidgetState();
}
class _InputWidgetState extends State<InputWidget> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPress: () {
// <-- onLongPress
widget.onDelete(widget.index);
},
child: new Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: <Widget>[
Column(
children: <Widget>[
Icon(
Icons.image,
size: 75,
)
],
),
Container(
margin: EdgeInsets.only(left: 80, right: 30),
child: Column(
children: <Widget>[
Text('Note'),
],
),
),
Column(
children: <Widget>[
Text("${widget.noteRec}"),
],
),
],
),
),
);
}
}