Flutter - afisare CircularProgressIndicator cand Provider incarca datele

Salutare,
intr-o aplicatie Flutter,in functie de item-ul selectat din widget-ul parinte (ParentWd) se incarca de pe server date in widget 2(ChildWd).am nevoie ca in timpul comunicarii cu serverul sa afisez un CircularProgressIndicator,ceea ce nu se intampla,datele sunt aduse ok.in codul de mai jos simulez request-ul cu Future.delayed
multumesc pt orice indicatie

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider.value(
            value: Child(),
          ),
        ],
        child: MaterialApp(
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: StartPage(),
        ));
  }
}

class StartPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: <Widget>[
            ParentWd(),//parent
            ChildWd(),//child
          ],
        ));
  }
}

class ParentWd extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(children: <Widget>[
      OutlineButton(
        child: Text('Parent 1'),
        shape: StadiumBorder(),
        onPressed: () async {
          await Provider.of<Child>(context, listen: false).getData(1);//load child data
        },
      ),
      OutlineButton(
        child: Text('Parent 2'),
        shape: StadiumBorder(),
        onPressed: () async {
          await Provider.of<Child>(context, listen: false).getData(2);/load child data
        },
      ),
    ]);
  }
}

class ChildWd extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: Provider.of<Child>(context, listen: false).getData(1),
      builder: (ctx, prevData) {
        if (prevData.connectionState == ConnectionState.waiting) {
          return Column(
            children: <Widget>[
              SizedBox(
                height: 150,
              ),
              Center(child: CircularProgressIndicator()),            ],
          );
        } else {
          if (prevData.error == null) {
            return Consumer<Child>(
              builder: (ctx, data, child) => GridView(
                padding: EdgeInsets.all(2),
                scrollDirection: Axis.vertical,
                shrinkWrap: true,
                children: data.children
                    .map(
                      (c) => OutlineButton(
                        child: Text(c.name),
                        shape: StadiumBorder(),
                        onPressed: () {},
                      ),
                    )
                    .toList(),
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 80,
                  childAspectRatio: 3 / 2,
                  crossAxisSpacing: 5,
                  mainAxisSpacing: 10,
                ),
              ),
            );
          } else {
            return Text('Error');
          }
        }
      },
    );
  }
}

class Child with ChangeNotifier {
  List<ChildItem> _children = [];

  List<ChildItem> get children {
    return [..._children];
  }

  Future<void> getData(int idP) async {
  return  Future.delayed(const Duration(seconds: 2), () {//simulate server get data with delay
      List<ChildItem> ch = [];
      ch.add(ChildItem(id: 1, name: 'Child 1', idParent: 1));
      ch.add(ChildItem(id: 2, name: 'Child 2', idParent: 1));
      ch.add(ChildItem(id: 3, name: 'Child 3', idParent: 2));

      _children = ch.where((c) => c.idParent == idP).toList();
      notifyListeners();
    });
  }
}

class ChildItem {
  final int id;
  final String name;
  final int idParent;

  ChildItem({
    @required this.id,
    @required this.name,
    @required this.idParent,
  });
}

cerceteaza aici poate gasesti ceva util, nu prea cunosc dart. Inca is la inceput

1 Like

multumesc.si eu sunt incepator.am gasit cum sa afisez CircularProgressIndicator dar nu reusesc sa-l leg de Provider

Se pare ca am gasit o solutie:din widgetul parinte nu mai fac interogarea,doar schimb indexul/id-ul parintelui si apelez notifyListeners() ceea ce face rebuild la wd abonate la provider…aici,in build fac efectiv interogarea si afisare indicator

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider.value(
            value: Child(),
          ),
        ],
        child: MaterialApp(
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: StartPage(),
        ));
  }
}

class StartPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: <Widget>[
            ParentWd(), //parent
            ChildWd(), //child
          ],
        ));
  }
}

class ParentWd extends StatefulWidget {
  @override
  _ParentWdState createState() => _ParentWdState();
}

class _ParentWdState extends State<ParentWd> {
  var _isInit = false;

  @override
  void didChangeDependencies() {
    if (!_isInit) {
      Future.delayed(Duration.zero).then((_) {
        Provider.of<Child>(context, listen: false).changeIndex(1);
      });
      _isInit = true;
    }
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Row(children: <Widget>[
      OutlineButton(
        child: Text('Parent 1'),
        shape: StadiumBorder(),
        onPressed: () async {
          Provider.of<Child>(context, listen: false).changeIndex(1);
        },
      ),
      OutlineButton(
        child: Text('Parent 2'),
        shape: StadiumBorder(),
        onPressed: () async {
          Provider.of<Child>(context, listen: false).changeIndex(2);
        },
      ),
    ]);
  }
}

class ChildWd extends StatefulWidget {
  @override
  _ChildWdState createState() => _ChildWdState();
}

class _ChildWdState extends State<ChildWd> {
  var _isInit = false;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: Provider.of<Child>(context, listen: true).getData(),
      builder: (ctx, prevData) {
        if (prevData.connectionState == ConnectionState.waiting) {
          return Column(
            children: <Widget>[
              SizedBox(
                height: 150,
              ),
              Center(child: CircularProgressIndicator()),
            ],
          );
        } else {
          if (prevData.error == null) {
            return Consumer<Child>(
              builder: (ctx, data, child) {
                return GridView(
                  padding: EdgeInsets.all(2),
                  scrollDirection: Axis.vertical,
                  shrinkWrap: true,
                  children: data.children
                      .map(
                        (c) => OutlineButton(
                          child: Text(c.name),
                          shape: StadiumBorder(),
                          onPressed: () {},
                        ),
                      )
                      .toList(),
                  gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                    maxCrossAxisExtent: 80,
                    childAspectRatio: 3 / 2,
                    crossAxisSpacing: 5,
                    mainAxisSpacing: 10,
                  ),
                );
              },
            );
          } else {
            return Text('Error');
          }
        }
      },
    );
  }
}

class Child with ChangeNotifier {
  var _parentIdx = 0;
  List<ChildItem> _children = [];

  List<ChildItem> get children {
    return [..._children];
  }

  void changeIndex(int idx) {
    _parentIdx = idx;
    notifyListeners();
  }

  Future<void> getData() async {
    return Future.delayed(const Duration(seconds: 1), () {
      //simulate server get data with delay
      List<ChildItem> ch = [];
      ch.add(ChildItem(id: 1, name: 'Child 1', idParent: 1));
      ch.add(ChildItem(id: 2, name: 'Child 2', idParent: 1));
      ch.add(ChildItem(id: 3, name: 'Child 3', idParent: 2));

      _children = ch.where((c) => c.idParent == _parentIdx).toList();
      //  notifyListeners();
    });
  }
}

class ChildItem {
  final int id;
  final String name;
  final int idParent;

  ChildItem({
    @required this.id,
    @required this.name,
    @required this.idParent,
  });
}
1 Like

Bravo, chiar o sa incerc si eu codul cand o sa anjung acasa, tu pe ce compilez web sau mobil ?

Interesant o sa mearga pe web…

momentan pe mobil