Ive been working on a multiple instance project. so i tried doing this in the counter app. but only first instance is updating. below is my all code.
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
InstanceModel selected = InstanceModel.instances.first;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: SizedBox(
height: 50,
child: Row(
children: [
const SizedBox(
width: 50,
),
Expanded(child: Container()),
Expanded(
flex: 3,
child: ListView.separated(
itemCount: InstanceModel.instances.length,
scrollDirection: Axis.horizontal,
separatorBuilder: (c, i) => const SizedBox(
width: 50,
),
itemBuilder: (context, i) {
final InstanceModel instance =
InstanceModel.instances[i];
final isSelected = selected == instance;
return SizedBox(
width: 80,
child: ElevatedButton(
onPressed: () {
selected = instance;
setState(() {});
},
style: ElevatedButton.styleFrom(
backgroundColor:
isSelected ? Colors.green : Colors.black,
),
child: Text(instance.name),
),
);
}),
),
],
),
),
),
const SizedBox(
height: 20,
),
const Text(
'You have pushed the button this many times:',
),
GetBuilder<InstanceController>(
tag: selected.name,
builder: (_) {
return Text(
'${selected.controller.count}',
style: Theme.of(context).textTheme.headline4,
);
}),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
selected.controller.increment();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Model class
import 'package:get/get.dart';
import 'package:train/instance_controller.dart';
class InstanceModel {
final InstanceController controller;
final String name;
InstanceModel({
required this.controller,
required this.name,
});
static List<InstanceModel> instances = [
InstanceModel(
name: "1",
controller:
Get.put<InstanceController>(InstanceController(), tag: "1")),
InstanceModel(
name: "2",
controller:
Get.put<InstanceController>(InstanceController(), tag: "2")),
];
}
and controller class
import 'package:get/get.dart';
class InstanceController extends GetxController {
var count = 0.obs;
void increment() {
count ;
update();
}
}
only calling setstate is updating the second instance. i dont understand where im wrong. any help will be appreciated---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CodePudding user response:
I really was confused at first that this might be some bug since logically your code is right, then I noticed that this about Flutter widgets replacing each by other on new state rather than completely removing that widget then adding it again in the widget tree.
on update state ( setState(() {})
), flutter searches first for widgets with the same type to replace each with other, in this situation, when you're expecting that GetBuilder
should trigger state for each separated unique controllers, flutter just update one with the other with saving it's state.
And to fix it, you should simply add a Key
to the GetBuilder
to tell flutter that each of it is unique like this:
GetBuilder<InstanceController>(
key: UniqueKey(), // add this
tag: selected.name,
builder: (_) {
return Text(
'${selected.controller.count}',
style: Theme.of(context).textTheme.headline4,
);
}),