Я новичок в Flutter и только что создал свое первое базовое приложение.Он использует просмотр списка в качестве главной страницы с FloatinActionButton, который переходит на другую страницу.На этой странице есть форма, которая возвращает объект на первую страницу.
После просмотра и прочтения большого количества видео и учебных пособий я не понимаю, почему просмотр списка моей главной страницы не обновляется,Как только я сверну приложение или перейду на другую страницу и вернусь, список будет обновляться, но не сразу после отправки формы.
Я использую шаблон BloC (просто изменил копирование + вставка из учебника)и StreamBuilder.
Вот мой main.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:vartest/sqlitedatabase/DatabaseBloc.dart';
import 'carts.dart';
import 'new_cart_form.dart';
import 'item_storage.dart';
import 'shopping_list.dart';
void main() {
runApp( MaterialApp(
title: 'Einkaufsliste',
home: MyApp(storage: ItemStorage()),
),);
}
class MyApp extends StatefulWidget {
final ItemStorage storage;
MyApp({Key key, @required this.storage}) : super(key: key);
@override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
final bloc = CartsBloc();
final blocCartItems = CartsBloc();
ItemStorage storage;
int id;
double sum;
@override
void dispose() {
bloc.dispose();
blocCartItems.dispose();
super.dispose();
}
var refreshKey = GlobalKey<RefreshIndicatorState>();
@override
void initState() {
super.initState();
bloc.getCarts();
sum = 0.0;
}
@override
Widget build(BuildContext context) {
final title = 'Einkaufsliste';
return MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: StreamBuilder<List<Carts>>(
stream: bloc.carts,
builder: (BuildContext context, AsyncSnapshot<List<Carts>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Carts cart = snapshot.data[index];
sum = 0.0;
return Dismissible(
key: UniqueKey(),
onDismissed: (direction) {
bloc.delete(cart.id);
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text(cart.shopName + " vom entfernt")));
},
background: Container(color: Colors.red),
child: ListTile(
leading: Text(sum.toStringAsFixed(2)),
title: Text(cart.shopName),
subtitle: Text(DateFormat('dd.MM.yyyy').format(new DateTime.fromMillisecondsSinceEpoch(cart.createdDate, isUtc : false))),
onTap: () async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ShoppingList(cart: cart),
));
}
),
);
},
);}else {
return Center(child: CircularProgressIndicator());
}}),
floatingActionButton: FloatingActionButton(
onPressed: _showNewCartForm,
tooltip: 'Increment',
backgroundColor: Colors.green,
child: Icon(Icons.camera,),
),
),
);
}
Future _showNewCartForm() async {
Carts newCart = await Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return AddCartFormPage();
},
),
);
if (newCart != null) {
setState(() {
bloc.add(newCart);
bloc.getCarts();
});
}
}
}
Моя форма (new_cart_form_data.dart
import 'package:flutter/material.dart';
import 'package:vartest/sqlitedatabase/DatabaseBloc.dart';
import 'carts.dart';
class AddCartFormPage extends StatefulWidget {
final List carts;
AddCartFormPage({Key key, @required this.carts}) : super(key: key);
@override
_AddCartFormPageState createState() => _AddCartFormPageState();
}
class _AddCartFormPageState extends State<AddCartFormPage> {
TextEditingController shopnameController = TextEditingController();
TextEditingController createdDateController = TextEditingController();
void submitItem(BuildContext context) {
if (shopnameController.text.isEmpty) {
print('Item need name');
} else {
var newCart = new Carts();
newCart.shopName = shopnameController.text;
newCart.createdDate = DateTime.now().millisecondsSinceEpoch;
Navigator.of(context).pop(newCart);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hinzufügen'),
),
body: Container(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 32.0,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: TextField(
controller: shopnameController,
decoration: InputDecoration(
labelText: 'Name',
)),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Builder(
builder: (context) {
// The basic Material Design action button.
return RaisedButton(
// If onPressed is null, the button is disabled
// this is my goto temporary callback.
onPressed: () => submitItem(context),
color: Colors.blue,
child: Text('Übernehmen', style: TextStyle(color: Colors.white),),
);
},
),
),
],
),
),
),
);
}
}
Мой BloC
import 'dart:async';
import 'package:vartest/carts.dart';
import 'package:vartest/cart_items.dart';
import 'Database.dart';
class CartsBloc {
final _cartsController = StreamController<List<Carts>>.broadcast();
get carts => _cartsController.stream;
dispose() {
_cartsController.close();
}
getCarts() async {
_cartsController.sink.add(await DBProvider.db.getAllCarts());
}
CartsBloc() {
getCarts();
}
delete(int id) {
DBProvider.db.deleteCarts(id);
getCarts();
}
add(Carts carts) {
DBProvider.db.newCarts(carts);
getCarts();
}
}