I am trying to implement a dynamic list view in flutter which could be increased by tapping the floating actin button. But the method in onPressed of floating action button is being updated only once.
Below is my code for both the UI and flutter bloc:-
import 'package:demo/bloc/main/demo_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Demo",
home: DemoApp(),
);
}
}
class DemoApp extends StatelessWidget {
const DemoApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
lazy: false,
create: (context)=>DemoBloc([54,4,598,984,654,87,5,897,65,46,84,65,4984,]),
child: Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: NumberList(),
floatingActionButton: BlocBuilder<DemoBloc, List<int>>(
builder: (context, state){
return FloatingActionButton(
onPressed: (){
BlocProvider.of<DemoBloc>(context).addItem(12);
}
);
},
),
),
);
}
}
class NumberList extends StatelessWidget {
const NumberList({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<DemoBloc, List<int>>(builder: (context, state) {
return ListView.builder(
itemCount: BlocProvider.of<DemoBloc>(context).state.length,
itemBuilder: (context, index) {
return Text(
BlocProvider.of<DemoBloc>(context).state[index].toString()
);
});
});
}
}
import 'package:flutter_bloc/flutter_bloc.dart';
class DemoBloc extends Cubit<List<int>>{
DemoBloc(List<int> initialState) : super(initialState);
addItem(int value){
print("adding item to the numbers list");
state.add(value);
emit(state);
}
removeItem(){
state.removeLast();
emit(state);
}
removeItemFrom(int index){
state.removeAt(index);
emit(state);
}
}
I am using print function inside addItem() function and it is executing and being printed in the console , but the list is not being updated except only once.
CodePudding user response:
You BlocProvider
needs to be higher up in the widget hierarchy. Right now, you create a new BloC every time the build function is called. That will wipe out any changes you made, because every change will trigger a build and every build will reset your state to the beginning.
Your BlocProvider
needs to be outside of any build function. You don't want to reset your data under any circumstances because of a rebuild.
You can put it in the main method as the root widget and make your app the child.
CodePudding user response:
try this
addItem(int value) {
print("adding item to the numbers list");
final newList = [...state];
newList.add(value);
emit(newList);
}
The problem is the list you emit after the first time is actually the same object. So you need to clone the list into brand new list. It is easier to use immutable object as bloc state. You can use freezed package for class and kt_dart or built_collection for collection data type. With immutable data type you have to make new object instead of mutating existing one so bloc can know that it is a new state.