1

I'm using the BLOC pattern to get the events and build my listview. I'm also using animation to appears each list. When I go to the child class, ItemEffect, I can't refresh parent class using BLOC method. In another word, when I go to ItemEffect class, the "await visitBloc.getVisits(contactId: contact.id);" in onItemClick function, couldn't refresh the parent class stream builder. I think something in animation stream builder, in ItemEffect class, cause losing the control of visit.bloc stream. I'm new in flutter and can't self this problem alone, can anyone help me, please?

class CustomerVisitsScreen extends StatefulWidget {
  Contact contact;
  int visitNumber =
      10000; // If we set 0 as inital set, the image appears after another one

  CustomerVisitsScreen(this.contact);

  @override
  _CustomerVisitsScreenState createState() => _CustomerVisitsScreenState();
}

class _CustomerVisitsScreenState extends State<CustomerVisitsScreen>
    with SingleTickerProviderStateMixin {
  VisitBloc visitBloc;
  final ContactBloc contactBloc = ContactBloc();
  final ListBloc listBloc = new ListBloc();

  @override
  void initState() {
    super.initState();
    //---
    visitBloc = VisitBloc(contactId: widget.contact.id);
    //---
    WidgetsBinding.instance.addPostFrameCallback((_) {
      getCategoryColorList();
      countVisits(widget.contact.id);
    });
  }

  @override
  void dispose() {
    listBloc.dispose();
    visitBloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
        textDirection: TextDirection.rtl,
        child: Scaffold(
            backgroundColor: Theme.of(context).backgroundColor,
            body: Container(
              decoration: BoxDecoration(
                  image: widget.visitNumber == 0
                      ? DecorationImage(
                          image: AssetImage("assets/Image/Add.png"),
                          fit: BoxFit.none,
                        )
                      : DecorationImage(
                          image: AssetImage("assets/Image/Background.png"),
                          fit: BoxFit.cover,
                          colorFilter: new ColorFilter.mode(
                              Colors.black.withOpacity(0.15),
                              BlendMode.dstATop),
                        )),
              child: Column(
                children: [
                  AppBar_SeaShape(context),
                  SizedBox(
                    height: 10,
                  ),
                  Expanded(
                    child: getVisitsWidget(),
                  ),
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () => onAddFactor(context, widget.contact),
              child: Icon(Icons.add),
            )));
  }

  Widget getVisitsWidget() {
    return StreamBuilder(
      stream: visitBloc.visits,
      initialData: <Visit>[],
      builder: (BuildContext context, AsyncSnapshot<List<Visit>> snapshot) {
        return visitListView(snapshot.data);
      },
    );
  }

  ListView visitListView(List<Visit> list) {
    listBloc.startAnimation(list.length, Duration(milliseconds: 50));
    return ListView.builder(
        itemCount: list.length,
        itemBuilder: (BuildContext context, int index) {
          final item = list[index];
          int _colorCat = getListColor(list[index]);
          return Dismissible(
            //--- Date and Time is combined as a key to generate uniqe KEY
            key: Key((item.visitDate + item.visitTime)),
            confirmDismiss: (DismissDirection direction) async {
              return await showDialog(
                context: context,
                builder: (BuildContext context) {
                  return MyAlertDialog();
                },
              );
            },
            onDismissed: (DismissDirection direction) {
              deleteVisit(item);
            },
            child: ItemEffect(context, list[index], index, widget.contact,
                Duration(milliseconds: 200), _colorCat),
          );
        });
  }

}

class ItemEffect extends StatefulWidget {
  final BuildContext context;
  final Visit visit;
  final int position;
  final Contact contact;
  final Duration duration;
  final int color;
  ItemEffect(this.context, this.visit, this.position, this.contact,
      this.duration, this.color);
  _ItemEffect createState() => new _ItemEffect();
}

class _ItemEffect extends State<ItemEffect> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<Offset> _offsetFloat;
  final VisitBloc visitBloc = VisitBloc();

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: widget.duration,
    );

    _offsetFloat = Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset.zero)
        .animate(_controller);

  }


  @override
  Widget build(BuildContext context) {
    return new StreamBuilder(
        stream: new ListBloc().listenAnimation,
        initialData: -1,
        builder: (context, AsyncSnapshot<int> snapshot) {
          if (snapshot.data >= widget.position && snapshot.data > -1)
            _controller.forward();
          return SlideTransition(
              position: _offsetFloat,
              child: Stack(
                alignment: Alignment.topLeft,
                children: [
                  Card(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10.0),
                    ),
                    color: Color(widget.color ?? 0),
                    child: Card(
                      color: Theme.of(context).cardColor,
                      elevation: 5.0,
                      shadowColor: Theme.of(context).accentColor,
                      margin: EdgeInsets.only(right: 15, top: 2),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10.0),
                      ),
                      child: ListTile(
                        title: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Row(
                              children: [
                                Text('${widget.visit.totalPrice}' ?? ""),
                                SizedBox(
                                  width: 10,
                                ),
                                Icon(
                                  Icons.payments_outlined,
                                  color: Colors.grey,
                                ),
                              ],
                            ),
                          ],
                        ),
                        subtitle: Text(widget.visit.category ?? ""),
                        onTap: () {
                          onItemClick(
                            context,
                            widget.contact,
                            widget.visit,
                          );
                        },
                      ),
                    ),
                  ),
                  alarmWidget(widget.visit),
                ],
              ));
        });
  }

 void onItemClick(BuildContext context, Contact contact, Visit visit) async {
    //--- Go to N ext Screen
    await Navigator.push(context,
        MaterialPageRoute(builder: (context) => FactorScreen(contact, visit)));
    //--- Turned Back to this Screen and Should Refresh List
    await visitBloc.getVisits(contactId: contact.id);
    // setState(() {});
  }
}
  • could you please add some image and explain more . – Sajjad Dec 24 '21 at 08:26
  • The above code creates a list of boxes on the screen. When the user presses a box, we get into "onItemClick" function and get to the next page. Imagine on the next page user changes the box color or even deletes the pressed box info from the database. When We turn back to the last page, the code line is yet in the "onItemClick" function on the "await visitBloc.getVisits(contactId: contact.id);" line. I expect if the code continues the "visitbloc" gets a new stream and refresh UI(for example delete the pressed box), but it doesn't happen. I can see changes if I close and reopen the screen. – Reza Asgharian Dec 24 '21 at 22:04

0 Answers0