Home > Back-end >  How to rebuild only specific item in List (RxList) after updating it properties
How to rebuild only specific item in List (RxList) after updating it properties

Time:09-09

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);
  }
}

  • Related