skip to Main Content

I’m new to Bloc and Flutter. I’m currently designing a financial/budget app.

The UI is simple the moment, I have 2 list views , one for displaying income, the other displays expense. The user presses a button and a form gets displayed for them to fill out (e.g. if it’s an income/expense, the amount, the category etc). The user then fills out the form and presses the save button.

I have one Bloc called FinanceBloc. When the save button is pressed, a SaveEvent is emitted from the widget. My Bloc handles it and once saved, it emits an IncomeSavedState or ExpenseSavedState. My issue is is that I have wrapped both list views with BlocBuilder with an if statement.. e.g.

Income List:

if (state is IncomeSavedState) {
  Return the list view for income
} else { return Text(“…”)} 

Expense List:

if (state is ExpenseSavedState) {
  Return the list view for expense
} else { return Text(“…”)}

Now the issue is that, IncomeSavedState and ExpenseSavedState are derived by the same parent abstract class. So when anything is saved, both lists are triggered. The side effect this has is that because the BlocBuilder NEEDS to return a widget, whenever an Income is saved, the ListView for expense is evaluated to the Text ‘…’ due to the ‘else’ code block and vice versa.

Is it possible to tell Bloc to not update the state? How can I maintain the state if I’m using 2 states of the same type in 2 different widgets?

I was thinking of having 2 Blocs; IncomeBloc and ExpenseBloc but later one , I’m planning on populating a line graph that’ll draw the amount of the expenditure so I don’t think I will be able to do that if they’re separate?

2

Answers


  1. If you really want to use ListView or it’s necessary to use it, you should implement the AutomaticKeepAliveClientMixin to ensure that the state is not lost. Otherwise, if you want a quick and simple solution, use SingleChildScrollView.

    Using AutomaticKeepAliveClientMixin with ListView:

    import 'package:flutter/material.dart';
    
    class MyListViewPage extends StatefulWidget {
      @override
      _MyListViewPageState createState() => _MyListViewPageState();
    }
    
    class _MyListViewPageState extends State<MyListViewPage> with AutomaticKeepAliveClientMixin {
      @override
      bool get wantKeepAlive => true;
    
      @override
      Widget build(BuildContext context) {
        super.build(context);
        return Scaffold(
          appBar: AppBar(title: Text('ListView Example')),
          body: ListView.builder(
            itemCount: 100,
            itemBuilder: (context, index) {
              return ListTile(title: Text('Item $index'));
            },
          ),
        );
      }
    }
    

    Using SingleChildScrollView for a quick and simple solution:

    import 'package:flutter/material.dart';
    
    class MySingleChildScrollViewPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('SingleChildScrollView Example')),
          body: SingleChildScrollView(
            child: Column(
              children: List.generate(100, (index) {
                return ListTile(title: Text('Item $index'));
              }),
            ),
          ),
        );
      }
    }
    

    Feel free to adjust the examples as needed for your specific use case!

    Login or Signup to reply.
  2. What you could do here is wrapping your lists to different BlocBuilder‘s and use buildWhen:

      BlocBuilder<FinanceBloc, FinanceState>(
        //use condition you need, you can check previous and next states
        buildWhen(prevState, nextState) => next is IncomeSavedState
        builder: (context, financeState) {
          return ...IncomeList...
        }
      );
    
    ...
      BlocBuilder<FinanceBloc, FinanceState>(
        //use condition you need
        buildWhen(prevState, nextState) => next is ExpenseSavedState
          builder: (context, financeState) {
            return ...ExpenseList...
          }
        );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search