Я пытаюсь обновить / перестроить маршрут под всплывающим окном, когда всплывающее окно выскочило, используя Navigator.pop (context). Во всплывающем окне пользователь может добавить что-то в список, а маршрут под (страницей) добавленного элемента отображается в ListView. Поэтому, в частности, мне нужно, чтобы мой ListView был в курсе актуального списка. Но ничего, что я еще не пробовал, сработало.
Как уже упоминалось, я уже пробовал довольно много вещей, в том числе: didPopNext () (с использованием RouteAware), changeExternalState (которую я не совсем понял), пытаясь передать функцию, содержащую только setState (() {}) и другие вещи.
Надеюсь, кто-нибудь может помочь с тем, как я могу перестроить ListView, когда всплывающее окно выскочило.
Заранее спасибо.
Этот пример должен довольно близко подвести итог моей проблемы (не мог показать вам реальный код, потому что он получил более 2000 строк, но основные элементы проблемы должны быть здесь):
import 'package:flutter/material.dart';
void main() => runApp(new MaterialApp(
home: MyPage()));
class PopupLayout extends ModalRoute<void> {
@override
Duration get transitionDuration => Duration(milliseconds: 300);
@override
bool get opaque => false;
@override
bool get barrierDismissible => false;
@override
bool get semanticsDismissible => true;
@override
Color get barrierColor =>
bgColor == null ? Colors.black.withOpacity(0.5) : bgColor;
@override
String get barrierLabel => null;
@override
bool get maintainState => false;
double top;
double bottom;
double left;
double right;
Color bgColor;
final Widget child;
PopupLayout(
{Key key,
this.bgColor,
@required this.child,
this.top,
this.bottom,
this.left,
this.right});
@override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
if (top == null) this.top = 10;
if (bottom == null) this.bottom = 20;
if (left == null) this.left = 20;
if (right == null) this.right = 20;
return GestureDetector(
onTap: () {},
child: Material(
type: MaterialType.transparency,
child: _buildOverlayContent(context),
),
);
}
Widget _buildOverlayContent(BuildContext context) {
return Container(
margin: EdgeInsets.only(
bottom: this.bottom,
left: this.left,
right: this.right,
top: this.top),
child: child,
);
}
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return FadeTransition(
opacity: animation,
child: ScaleTransition(
scale: animation,
child: child,
),
);
}
}
class PopupContent extends StatefulWidget {
final Widget content;
PopupContent({
Key key,
this.content,
}) : super(key: key);
_PopupContentState createState() => _PopupContentState();
}
class _PopupContentState extends State<PopupContent> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: widget.content,
);
}
}
popupContent(BuildContext context, Widget widget,
{BuildContext popupContext}) {
Navigator.push(
context,
PopupLayout(
top: 120,
left: 20,
right: 20,
bottom: 120,
child: PopupContent(
content: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: widget,
),
),
),
);
}
Widget popupWidget(BuildContext context) {
return new Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("This is a popupPage"),
FlatButton(
onPressed: () {
list.add("Irrelevant");
Navigator.pop(context); //The rebuild of the page underneath, needs to be called when this pops
},
child: Text("Press me to change text on home page"),
),
]
),
);
}
List list = [];
class MyPage extends StatefulWidget {
@override
createState() => MyPageState();
}
class MyPageState extends State<MyPage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Container(
width: 300,
height: 400,
child: ListView.builder(
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return Center(
child: Text(index.toString()),
);
},
),
),
),
Center(
child: FlatButton(
onPressed: () {
popupContent(context, popupWidget(context));
},
child: Text("Press me for popup window"),
),
),
Center(
child: FlatButton(
onPressed: () {
setState(() {});
},
child: Text("Press me to rebuild page (setState)"),
),
),
]
),
);
}
}