2

我正在使用pull_to_refresh包。

Stack()有两个元素。其中之一是Refresher(). 当我在屏幕上下拉,激活刷新动画时,该build方法被不断调用。问题是我的堆栈中的第二个小部件构建起来非常复杂并且需要一些时间。我想防止在触发Refresher-Animation 时一直构建它。这可能吗?

我的简化代码如下所示:

@override
  Widget build(BuildContext context) {
    return Scaffold(
        key: _scaffoldKey,
        body: Stack(children: <Widget>[
          SafeArea(
              child: Column(children: [
            Expanded(
              child: Container(
                  margin: EdgeInsets.all(0),
                  width: 100.w,
                  constraints: const BoxConstraints.expand(),
                  child: SizedBox(
                              width: 100.w,
                              child: Refresher( refresher stuff )
                              )
                          )
                      )
                  )
              ),
              SecondItem()
          )
      )
 }

不知何故,build方法SecondItem总是被调用。不是build整个脚手架的方法。

4

2 回答 2

0

由于我无法真正复制该问题,因此我构建了一个实现刷新的工作结构。

首先是主要的小部件,在我的例子MyHomePage中。此小部件将ScaffoldandStackFirstWidgetand实现SecondWidget为子项。

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    Key? key,
  }) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: const <Widget>[
          FirstWidget(),
          SecondWidget(),
        ],
      ),
    );
  }
}

FirstWidget是一个状态为 a 的statefull小部件counter。它refresher使用特定的controller. 一旦触发了刷新,它就会调用set state并更新counter他的状态。那应该只会再次触发他的构建,而不是其他任何构建。我实现了 aText来显示counter每次刷新时增加的值,并实现了 aPrint来公开构建。

class FirstWidget extends StatefulWidget {
  const FirstWidget({
    Key? key,
  }) : super(key: key);

  @override
  State<FirstWidget> createState() => _FirstWidgetState();
}

class _FirstWidgetState extends State<FirstWidget> {
  late int _counter;
  late RefreshController _refreshController;

  @override
  void initState() {
    _counter = 1;
    _refreshController = RefreshController(initialRefresh: false);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print('First widget built');
    return SafeArea(
      child: Column(
        children: [
          Container(
            margin: const EdgeInsets.all(0),
            width: double.infinity,
            height: 500,
            color: Colors.red,
            child: SmartRefresher(
              controller: _refreshController,
              onRefresh: () async {
                setState(() {
                  _counter++;
                });
                await Future.delayed(const Duration(milliseconds: 1000));
                _refreshController.refreshCompleted();
              },
            ),
          ),
          Text("Counter: $_counter"),
        ],
      ),
    );
  }
}

最后我们得到SecondWidget了另一个带有print语句的简单小部件。在构建的情况下,它会在控制台上写入。 刷新时FirstWidget,第二个不会构建,因为他的状态没有改变

class SecondWidget extends StatefulWidget {
  const SecondWidget({
    Key? key,
  }) : super(key: key);

  @override
  State<SecondWidget> createState() => _SecondWidgetState();
}

class _SecondWidgetState extends State<SecondWidget> {
  @override
  Widget build(BuildContext context) {
    print('Second widget built');
    return const Center(child: Text('Second here!'));
  }
}

您的问题的可能原因。

可能是在刷新时,您实际上正在更新父小部件的状态,在级联时会导致重新构建您的第二个小部件。如果状态处理正确,并且您的第二个小部件不依赖于您的第一个小部件状态,则刷新不应重建第二个。

于 2022-03-04T14:37:35.187 回答
0

如果您的第二个项目不想刷新,则将其添加为单独的类,例如,

 Expanded(
              child: Container(
                  margin: EdgeInsets.all(0),
                  width: 100.w,
                  constraints: const BoxConstraints.expand(),
                  child: SizedBox(
                              width: 100.w,
                              child: Refresher( refresher stuff )
                              )
                          )
                      )
                  )
              ),
              SecondItem()
          )


class SecondItem extends StatefulWidget {
  @override
  _SecondItemState createState() => _SecondItemState();
}

class _SecondItemState extends State<SecondItem> {
  int counter = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Text("Your Second Widget"),
    );
  }
}

现在,当您刷新 FirstItem() 时,您的 SecondItem()将不会刷新

于 2022-03-01T07:50:41.387 回答