GetX 和 ListView 问题

GetX and ListView issues

我在 GetX 的整个状态管理上遇到了很多问题,所以我自然会遇到一些问题。

我从 firebase 获取了一个集合,我将其放入填充有 Card 小部件 (CustomCard()) 的列表视图中,每个文档都放入一个 Card 小部件中。在此 Card 小部件中,我有一个布尔值,用于控制在点击 Card 时是否应展开卡片(只需添加一个 Row())。我面临的问题是,如果对这个布尔值使用 GetX,所有卡片都会触发,而不是每张卡片。在某种程度上,这似乎合乎逻辑,因为我只有一个控制器来管理这个布尔值。

所以澄清一下,bool isCardExpanded 似乎对所有卡片小部件都是全局的,这意味着如果我点击一张卡片,所有 张卡片都会展开,这不是我想要的想。我需要他们单独行动。 列表视图中的每张卡片是否需要一个单独的控制器,或者这是否可以通过其他方式解决?

控制器

class Controller extends GetxController {
  RxBool isCardExpanded = false.obs;

  void changeExpanded() {
    isCardExpanded.value = !isCardExpanded.value;
    update();
  }
}

列表视图:

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

卡片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'),
                      ],
                    ),
                ],
              ),
            ),
          ),
        );
      }
    }

    

期望的结果:

实际结果:

因为您的控制器实例只初始化一次。

要解决您的问题,您需要制作一个 List 具有 Controller 中卡片状态的 List

或者不使用状态管理工具,而是将_isExpanded值单独放在_CustomCardStateclass中。并使用 setState() 函数。

编辑

还有一种方法是在创建控制器时使用 tag 参数,例如 Get.create(someController, tag: TAG_NAME);