Flutter:在创建 GridView.builder 项目后,稍后在代码中动态更新

Flutter: Dynamically update items of GridView.builder later in code after they have been created

提问人:bbr 提问时间:11/17/2023 最后编辑:James Zbbr 更新时间:11/20/2023 访问量:28

问:

我在按下“+”按钮时添加了 3 个带有 GridView.builder 的容器。

这是我的 GridView.builder 代码:

Obx(
  () => GridView.builder(
    itemCount: c.gridItems.length,
    shrinkWrap: true,
    gridDelegate:
        SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
            crossAxisSpacing: 20.dp,
            mainAxisSpacing: 10.dp,
            mainAxisExtent: 60.dp),
    itemBuilder: (BuildContext context, int index) {
      final isCurrentContainer =
          (index == c.audioPlayerCurrentIndex % 3);
      Color containerColor = isCurrentContainer
          ? Colors.blue
          : Colors.grey;

      return GestureDetector(
        onTap: () { 

          showDialog(
            context: context,
            builder: (BuildContext context) =>
                StatefulBuilder(
              builder: (context, state) => KeysDialog(),
            ),
          );
        },
        child: Obx(
          () => Container(
            width: 60.dp,
            height: 60.dp,
            color: containerColor,
            child: Center(
              child: Text(
                c.gridItems[index],
                style: white22TextStyle,
              ),
            ),
          ),
        ),
      );
    },
  ),

这是我的控制器。我正在使用 getX:

class Controller extends GetxController {
  var gridItems = [].obs;

  var isMetronomeSelected = false.obs;
  var isBassSelected = false.obs;
  var isDrumsSelected = false.obs;

  var tonalitySelected = 'Major'.obs;
  var keySelected = 'A'.obs;
  var rhythmsFolderSelected = 'Slow Dancing'.obs;
  var bpmSliderValue = 95.0.obs;

  var assetSources = [].obs;
  var audioPlayerCurrentIndex = 0;
  var audioPlayerLoopCount = 0.obs;
}

我想在按下播放按钮时根据当前播放的声音(容器)更改容器的颜色。我在播放按钮的 onPress 上调用这个 playAudio() 方法

Future<void> playAudio() async {
    await audioPlayer
        .play(AssetSource(c.assetSources[c.audioPlayerCurrentIndex]));
    print(c.assetSources.length);
    print(c.assetSources);

    await audioPlayer.onPlayerComplete.first;

    c.audioPlayerLoopCount.value++;

    // Check if all audios have played the same number of times
    if (c.audioPlayerLoopCount.value == c.assetSources.length) {
      c.audioPlayerLoopCount.value = 0;

      c.audioPlayerCurrentIndex = 0;
      playAudio();
    } else {
      // Play the next audio
      c.audioPlayerCurrentIndex =
          (c.audioPlayerCurrentIndex + 1) % c.assetSources.length;
      playAudio();
    }
  }

我想将audioPlayerCurrentIndex与GridView项的索引进行比较,但是这些项的索引在播放按钮调用时不会更新。因此,一旦我创建了 2 个容器,它始终保持“3”。

我错过了一些简单的东西吗?

Flutter 飞镖 gridview flutter-getx

评论


答:

0赞 smita 11/20/2023 #1

该问题可能与在控制器中管理 audioPlayerCurrentIndex 状态的方式有关。

确保 audioPlayerCurrentIndex 中的更改会触发 GridView.builder 的重新生成。为此,您需要在 Controller 中将其显式标记为可观察。您可以将 RxInt 用于此目的:

class Controller extends GetxController {
  var gridItems = [].obs;

  // Define audioPlayerCurrentIndex as RxInt
  var audioPlayerCurrentIndex = 0.obs;

  // Other variables...
}

鉴于:

  Future<void> playAudio() async {
  // ... Your existing code ...

  // Update audioPlayerCurrentIndex when audio is played
  c.audioPlayerCurrentIndex.value =
  (c.audioPlayerCurrentIndex.value + 1) % c.assetSources.length;

  playAudio();
}

此更改应确保当 audioPlayerCurrentIndex 发生更改时,观察到它的 Obx 小部件将触发重新生成,并相应地更新 UI,包括基于当前播放的音频的 GridView.builder 中容器的颜色。