Флаттер поток добавить данные на другую страницу - PullRequest
0 голосов
/ 25 февраля 2019

Я новичок в 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();
  }
}

1 Ответ

0 голосов
/ 26 февраля 2019

Вы должны сообщить, что внутреннее состояние объекта изменилось с помощью метода setState().Фреймворк будет планировать сборку для State объекта.Когда вы вернетесь на предыдущую страницу, добавьте действие, в котором вы будете обновлять данные.

Navigator.of(context).push(MaterialPageRoute(
  builder: (context) => ShoppingList(cart: cart),
)).then((newCart) {
   // back to this page
   setState(() {
     // update the cart/data here
   })
});
...