I have problem with updating my list after updating one item. I'm using GetX for state managment. It works fine when I add an item to my list, but not when i update some element. But I want to rebuild also specific element (TestInternalWidget) when I change some property in list. I want to avoid rebuilding the entire list. For testing when I double click on an element, a new element should be added (It works). And when I hold down a specific element, it should change
Here is my controller file "testcontroller.dart" for testing with item model class:
import 'package:get/get.dart';
class item {
String a = "";
String b = "";
item(String a, String b)
{
this.a = a;
this.b = b;
}
}
class TestController extends GetxController {
var itemsList = <item>[].obs;
@override
void onInit() {
print("init controller");
fetchItems();
super.onInit();
}
updateItem(int index){
print("UPDATING");
itemsList[index].a = "xxxxx";
itemsList[index].b = "XXXXX";
}
void fetchItems() async{
print("fetching items");
var item1 = item("aaaaa", "AAAAA");
var item2 = item("bbbbb", "BBBBB");
itemsList.add(item1);
itemsList.add(item2);
}
addItem()
{
print("ADDING");
var newItem = item("ccccc", "CCCCCC");
itemsList.add(newItem);
}
}
Here is my "main.dart" file:
import 'package:camera_app/views/widgets/testwidget.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'controllers/testcontroller.dart';
void main() async {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final TestController testController = Get.put(TestController());
return GetMaterialApp(
title: 'test',
home: Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black54),
backgroundColor: Color(0xfffee6dc),
centerTitle: true,
),
backgroundColor: Color(0xfffff6f7),
body: Obx(() => ListView.builder(
cacheExtent: 10,
addAutomaticKeepAlives: true,
physics: BouncingScrollPhysics(),
//physics : NeverScrollableScrollPhysics(),
itemCount: testController.itemsList.length,
itemExtent: 120,
itemBuilder: (context, index) {
print("item build");
return InkWell(
onLongPress:() {
testController.updateItem(index);
},
onDoubleTap: () {
testController.addItem();
},
child: Obx(()=> TestInternalWidget(testController.itemsList[index].a))
);
})
)
)
);
}
}
And last this is my test widget (testwidget.dart) used in list:
import 'package:flutter/material.dart';
class TestInternalWidget extends StatelessWidget {
String text= "";
TestInternalWidget(this.text);
@override
Widget build(BuildContext context) {
print("internal widget build");
return Container(
child:Text(text),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: Color(0xffE4CFC6)
)
);
}
}
CodePudding user response:
IN GetX, the reactive variable reflects the changes in real-time if updated the item is itself.
But, if you just want to update a single attribute in the item, you have to refresh
the reactive variable.
class TestController extends GetxController {
var itemsList = <item>[].obs;
@override
void onInit() {
print("init controller");
fetchItems();
super.onInit();
}
updateItem(int index){
print("UPDATING");
itemsList[index].a = "xxxxx";
itemsList[index].b = "XXXXX";
itemsList.refresh();
}
void fetchItems() async{
print("fetching items");
var item1 = item("aaaaa", "AAAAA");
var item2 = item("bbbbb", "BBBBB");
itemsList.add(item1);
itemsList.add(item2);
}
addItem()
{
print("ADDING");
var newItem = item("ccccc", "CCCCCC");
itemsList.add(newItem);
}
}