GetX and ListView issues

307

Because your controller instance initializes only once.

To solve your problem, you need to make a List that has the status of the cards in the Controller.

Or don't use the State management tool, but separately place the _isExpanded value in the _CustomCardState class. And use the setState() function.

EDIT

There is another way by using the tag argument when creating the controller like Get.create(someController, tag: TAG_NAME);

Share:
307
krumpli
Author by

krumpli

Updated on January 04, 2023

Comments

  • krumpli
    krumpli over 1 year

    I have quite the problem wrapping my head around the whole state management of GetX so naturally I'm facing some issues.

    I'm getting a collection from firebase which I put into a listview populated with Card widgets (CustomCard()), each document into a Card widget. In this Card widget I have a boolean that controls whether the card should be expanded (simply by Adding a Row()) or not if Card is tapped. The issue I'm facing is that if use GetX for this boolean, all the cards will trigger and not each individual card. In a way this seems logical because I only have one controller that manages this boolean.

    So to clarify, bool isCardExpanded seem to be global for all Card widgets meaning that if I tap one card, ALL cards will expand, which is not what I want. I need them to act individually. Do I need one separate controller for every Card in the list view or is this solvable in another way?

    Controller

    class Controller extends GetxController {
      RxBool isCardExpanded = false.obs;
    
      void changeExpanded() {
        isCardExpanded.value = !isCardExpanded.value;
        update();
      }
    }
    

    ListView:

    class CustomScreen extends State<CustomScreen>
            implements ItemScreenInterface {
          Controller ctrl = Get.find();
          @override
          Widget build(BuildContext context) {
            return StreamBuilder(
              stream: FirebaseFirestore.instance
                  .collection(someCol)
                  .doc(SomeDoc)
                  .collection(anotherCol).snapshots(),
              builder: (BuildContext context, AsyncSnapshot snapshot) {        
                return Column(
                  children: [
                    Expanded(
                      child: ListView.builder(
                            shrinkWrap: true,
                            itemCount: snapshot.data.docs.length,
                            itemBuilder: (_, i) {
                              return CustomCard( // <------------ Card widget
                                  document: snapshot.data.docs[i]);
                            }),
                    )
                  ],
                );
              },
            );
          }
    

    Card class

    class CustomCard extends StatefulWidget {
      CustomCard({required this.doc});
      var doc;
      @override
      _CustomCardState createState() => _CustomCardState();
    }
        class _CustomCardState extends State<CustomCard> {
          Controller ctrl = Get.find();
          RxBool _isCardExpanded = false.obs;
        
          @override
          void initState() {
            super.initState();
          }
        
          @override
          Widget build(BuildContext context) {
            return Card(
              child: GestureDetector(
                onTap: () {
                  ctrl.changeExpanded(); // <-- change bool 
                },
        
                child: Padding(
                  padding: EdgeInsets.all(2),
                  child: Column(
                    children: <Widget>[
                      Row(
                          children: <Widget>[
                            Text('Top Part')
                          ]),
                      if (_isCardExpanded.value) Divider(thickness: 2),
                      if (_isCardExpanded.value) // Controlled by _isCardExpanded. Add Row if true
                        Row(
                          children: <Widget>[
                            Text('EXPANDED'),
                          ],
                        ),
                    ],
                  ),
                ),
              ),
            );
          }
        }
    
        
    

    Desired outcome:

    enter image description here

    Actual outcome:

    enter image description here

  • krumpli
    krumpli about 2 years
    Thank you, this is what I suspected. I was wondering what the upside was with GetX compared to just setState() in the Card class, which i was using.