I have a list of objects, but I want to change the state of one object to "isLoading" where it will have a different title, etc.
I'm building my list view:
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
body: Obx(() => buildListView(context)));
}
Widget buildListView(BuildContext context) {
return ListView.builder(
itemCount: controller.saveGames.length,
itemBuilder: (context, index) {
final saveGame = controller.saveGames.elementAt(index);
return saveGame.isLoading
? buildListTileIsLoading(context, saveGame)
: buildListTile(context, saveGame);
});
}
ListTile buildListTile(BuildContext context, SaveGame saveGame) {
return ListTile(
onTap: () => controller.process(saveGame)
);
}
The controller:
class SaveGameController extends GetxController {
final RxList<SaveGame> saveGames = <SaveGame>[].obs;
void process(SaveGame saveGame) {
saveGame.working = true;
update();
}
}
Where have I gone wrong here?
edits: Added more code
CodePudding user response:
So despite the fact, I'm only updating one object in the list and not modifying the content of the list (adding/removing objects) I still need to call saveGames.refresh();
An oversight on my end didn't think you'd need to refresh the entire list if you're just changing the property on one of the objects.
Good to know :)
CodePudding user response:
update()
is used with GetBuilder()
obs()
is used with obx()
you need to make a change on list to update widgets
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_navigation/get_navigation.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetMaterialApp(
onInit: () {
Get.lazyPut(() => SaveGameController());
},
home: const HomePage(),
);
}
}
class HomePage extends GetView<SaveGameController> {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(), body: Obx(() => buildListView(context)));
}
Widget buildListView(BuildContext context) {
return ListView.builder(
itemCount: controller.saveGames.length,
itemBuilder: (context, index) {
final saveGame = controller.saveGames.elementAt(index);
return buildListTile(context, saveGame);
});
}
ListTile buildListTile(BuildContext context, SaveGame saveGame) {
return ListTile(
tileColor: saveGame.working ? Colors.red : Colors.yellow,
title: Text(saveGame.name),
onTap: () => controller.process(saveGame));
}
}
class SaveGameController extends GetxController {
final RxList<SaveGame> saveGames = <SaveGame>[
SaveGame(id: 0, name: 'a', working: false),
SaveGame(id: 1, name: 'b', working: false),
SaveGame(id: 2, name: 'c', working: false)
].obs;
void process(SaveGame saveGame) {
final index = saveGames.indexWhere((element) => element.id == saveGame.id);
saveGames
.replaceRange(index, index 1, [saveGame.copyWith(working: true)]);
}
}
class SaveGame {
final int id;
final String name;
final bool working;
SaveGame({required this.id, required this.name, required this.working});
SaveGame copyWith({int? id, String? name, bool? working}) {
return SaveGame(
id: id ?? this.id,
name: name ?? this.name,
working: working ?? this.working);
}
}