flutter中修改列表时保持滚动位置

问题描述 投票:0回答:1

我有一个列表,显示具有不同高度的元素(它也可以为零,这意味着元素被隐藏),并且我有一个滑块,可以控制元素使用特定方程的高度。问题是,例如,如果我站在第 15 个元素上,并且我开始增加元素的高度,则位置 0,...,14 中的元素“开始将”列表中的第 15 个元素向下推,然后我最终失去了我的职位。 我尝试使用滚动控制器的 JumpTo 方法,但问题是因为高度不同,我无法计算出我需要的确切偏移量。 有办法解决这个问题吗?

我尝试计算偏移量,但效果不佳。

flutter flutter-animation flutter-listview maintainscrollpositionon
1个回答
0
投票

这确实具有挑战性。一种可能的方法是估计元素高度并使用

jumpTo
方法滚动到估计的偏移量。

通过汇总当前位置上方的高度来计算估计的偏移量。确定缓冲区或填充以防止特写滚动。使用

jumpTo
ScrollController
方法应用偏移。

你可以试试这个例子

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ScrollController _scrollController = ScrollController();

  // Store the current slider value that determines element heights
  double _sliderValue = 0.0;

  // Store the estimated offset when the slider is changed
  double _estimatedOffset = 0.0;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_scrollListener);
  }

  void _scrollListener() {
    // Calculate the estimated offset when scrolling
    _estimatedOffset = _calculateEstimatedOffset();
  }

  double _calculateEstimatedOffset() {
    double estimatedOffset = 0.0;

    for (int i = 0; i < _getCurrentElementIndex(); i++) {
      // Calculate the estimated height of each element
      double estimatedElementHeight = _calculateElementHeight(i);
      estimatedOffset += estimatedElementHeight;
    }

    // Add a buffer to the estimated offset
    double buffer = 20.0; // You can adjust this value
    estimatedOffset -= buffer;

    return estimatedOffset;
  }

  int _getCurrentElementIndex() {
    // Calculate the current element index based on your logic
    // This could be based on the slider value or other factors
    // For example: (_sliderValue * myList.length).toInt()
    return 0;
  }

  double _calculateElementHeight(int index) {
    // Calculate the estimated height of the element at the given index
    // This could be based on the slider value or other factors
    return 100.0; // Replace with your logic
  }

  void _updateSliderValue(double newValue) {
    setState(() {
      _sliderValue = newValue;
      _estimatedOffset = _calculateEstimatedOffset();
      _scrollController.jumpTo(_estimatedOffset);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        controller: _scrollController,
        itemCount: myList.length,
        itemBuilder: (context, index) {
          // Build your list items based on the slider value and other factors
          // You can use the _sliderValue and _calculateElementHeight methods here
          return MyListItem();
        },
      ),
      bottomNavigationBar: Slider(
        value: _sliderValue,
        onChanged: _updateSliderValue,
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.