如何重新定位小部件而不在Flutter中重建其子部件?

如何重新定位小部件而不在Flutter中重建其子部件?,flutter,dart,flutter-animation,Flutter,Dart,Flutter Animation,在我的flatter项目中,我想使用定位小部件在屏幕上重新定位列表,以便用户可以手动或使用动画移动列表 我所做的工作非常有效,但我发现,每次移动列表时,列表中的每一项都会重新生成,这会导致一些性能问题 以下是一个基本示例: class TestPositionedPage extends StatefulWidget { @override _TestPositionedPageState createState() => _TestPositionedPageState(); }

在我的flatter项目中,我想使用
定位
小部件在屏幕上重新定位列表,以便用户可以手动或使用动画移动列表

我所做的工作非常有效,但我发现,每次移动列表时,列表中的每一项都会重新生成,这会导致一些性能问题

以下是一个基本示例:

class TestPositionedPage extends StatefulWidget {
  @override
  _TestPositionedPageState createState() => _TestPositionedPageState();
}

class _TestPositionedPageState extends State<TestPositionedPage> {

  double _yPage = 0;

  Widget _getItem(int position) {
    print("get item at $position");
    return ListTile(title: Text("Item at position $position"));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Stack(
          children: [
            Align(
              alignment: Alignment.topRight,
              child: FlatButton(
                onPressed: () {
                  setState(() => _yPage = Random().nextDouble() * 500);
                },
                child: Text("MOVE"),
                color: Colors.redAccent,
              ),
            ),
            Positioned(
              left: 0,
              top: _yPage,
              child: Container(
                width: 700,
                height: 700,
                child: ListView.builder(
                  itemCount: 100,
                  itemBuilder: (BuildContext context, int position) => _getItem(position),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
这意味着每次重新定位列表时,它也会重新生成,即使列表中没有任何更改

因此,我的问题是:是否有一种方法可以防止每次重新定位列表时重建每个项目,是否有一种方法可以缓存列表渲染,以便在重新定位时提高性能


谢谢。

当您调用
setState(()=>\u yPage=Random().nextDouble()*500)再次重建整个树,这导致列表也被重建。相反,只需构建一次列表并重新使用即可

Widget _myList;
  
  Widget initList(){
   return ListView.builder(
      itemCount: 100,
      itemBuilder: (BuildContext context, int position) => _getItem(position),
    );
  }

  @override
  void initState() {
    _myList = initList();
    super.initState();
  }
然后以这种方式使用列表

Positioned(
    left: 0,
    top: _yPage,
    child: Container(
        width: 700,
        height: 700,
        child: _myList
        ...
            

谢谢也就是说,经过一些测试后,它不会提高性能,如果我旋转屏幕,可能会出现一些问题,例如,如果我在
initList()函数中使用
MediaQuery.of(context)
。。。你知道吗?你有什么样的性能问题吗?当我使用
GestureDetector
小部件移动带有平移事件的列表时,帧速率约为24 fps,假设你在调试模式下尝试,这是非常糟糕的(不可怕,但仍然远没有达到预期的60 fps…)。发布模式呢?不,是发布模式(实际上是配置文件模式)。。。但我继续调查,问题可能在别处。
Positioned(
    left: 0,
    top: _yPage,
    child: Container(
        width: 700,
        height: 700,
        child: _myList
        ...