加载巨大列表时 Flutter ListView.separated 掉帧

Flutter ListView.separated frame drop when loading huge list

我正在尝试在 flutter 中为 windows 显示一个 lazy list。该列表中有 大约 2300 个元素。该列表位于 FutureBuilder 中,其未来是从 Hive 数据库中获取 2300 个元素。列表中的每个 元素都是一个具有某些属性的 MaterialButton。快速滚动时我滚动不流畅。一些 帧被删除 。我已经尝试 cacheextend 并将 automatickeepalives 设置为 true。 仍然有同样的问题。当 ItemExtend 设置为较大的数字(比如 40)时,scrollView 工作正常 而不会掉帧。在发布模式下,它有更好的性能,但仍然有一些帧被丢弃。这个问题的最佳解决方案是什么?

//this Rawscrollbar is returned if the future is have some data
RawScrollbar(
                    isAlwaysShown: true,
                    controller: scrollControllerMLC,
                    thickness: context.percentWidth * .8,
                    radius: Radius.zero,
                    thumbColor:
                        SearchLeftContainerColors.headPoolListThumbColor,
                    child: ListView.separated(
                      padding: EdgeInsets.fromLTRB(
                          context.percentWidth * .5,
                          context.percentHeight * 0,
                          context.percentWidth * 1,
                          context.percentHeight * 1),
                      itemCount: lengthOfBoxes,
                      controller: scrollControllerMLC,
                      // addAutomaticKeepAlives: true,
                      // physics: NeverScrollableScrollPhysics(),
                      itemBuilder: (context, int index) {
                        return ListButtonMEDLC(data[index], index);
                      },
                      separatorBuilder: (BuildContext context, int index) {
                        return Divider(
                          color: SearchLeftContainerColors
                              .headsPoolSeparatorColour,
                          height: 1,
                        );
                      },
                    ));




class ListButtonMEDLC extends StatelessWidget {
  final String text;
  final int index;
  ListButtonMEDLC(this.text, this.index);
  @override
  Widget build(BuildContext context) {
    return MaterialButton(
      color:
          (context.watch<ListButtonColorChangerMEDLC>().isSelectedList[index])
              ? SearchLeftContainerColors.headPoolListSelectedColor
              : SearchLeftContainerColors.headPoolListColor,
      hoverColor:
          (context.watch<ListButtonColorChangerMEDLC>().isSelectedList[index])
              ? SearchLeftContainerColors.headPoolListSelectedColor
              : SearchLeftContainerColors.headPoolListHoverColor,
      highlightColor: SearchLeftContainerColors.headPoolListHighLightedColor,
      child: Align(
        alignment: Alignment.centerLeft,
        child: Text(
          text,
          style: TextStyle(
              fontSize: context.percentWidth * 1.1,
              color: (context
                      .watch<ListButtonColorChangerMEDLC>()
                      .isSelectedList[index])
                  ? Colors.white
                  : Colors.black),
        ),
      ),
      onPressed: () {
        context.read<ListButtonColorChangerMEDLC>().changeIsSelectedList(index);
      },
    );
  }
}

//this it the future of the future builder;
loadDrugBox() async {
  Map boxes = await DB.boxes.getBoxAsMap("drugs");
  lengthOfBoxes = boxes.length;
  return boxes;
}

//Provider
class ListButtonColorChangerMEDLC extends ChangeNotifier {
  List<bool> isSelectedList = List.generate(lengthOfBoxes, (index) => false);

  changeIsSelectedList(int indexOfSelected) {
    for (int i = 0; i < lengthOfBoxes; i++) {
      if (i == indexOfSelected) {
        isSelectedList[i] = true;
      } else
        isSelectedList[i] = false;
    }
    notifyListeners();
  }
}

是的。我通过用 gestureDetector 替换昂贵的小部件 material 按钮解决了这个问题。