首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当调用SetState()时,如何避免UniqueKey闪烁的颤动FutureBuilder?

当调用SetState()时,如何避免UniqueKey闪烁的颤动FutureBuilder?
EN

Stack Overflow用户
提问于 2020-11-12 19:03:04
回答 1查看 358关注 0票数 1

我有一个PageView (父PageView),它的每个页面都是一个返回FutureBuilderStatefulWidgetFutureBuilder本身也将返回一个PageView(子PageView)。因为我希望父PageView和子小部件都保留页面,所以父小部件和子小部件都是用AutomaticKeepAliveClientMixin实现的。

每个页面都分配了一个UniqueKey,因为这些页面是动态的,这意味着用户可以删除某些页面或添加页面。然而,当调用SetState()时,有两个问题:1整个页面闪烁;2子PageView跳回到索引为0的页面。

如果我不使用UniqueKey,这两个问题就会消失。但是在添加或删除页面后,您不能刷新页面。

任何建议都很感谢,谢谢!

显示闪烁的代码:

代码语言:javascript
运行
复制
void main() async {
  runApp(
    MaterialApp(
      title: 'Test',
      home: Scaffold(
        body: Bar(),
      ),
    ),
  );
}

class Bar extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _BarState();
}

class _BarState extends State<Bar> {
  List<Widget> pages;

  final controller = PageController(initialPage: 0, keepPage: true);
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    pages = [
      Center(child: PageWithFutureBuilder(key: UniqueKey())),
      Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          PageWithFutureBuilder(key: UniqueKey()),
          RaisedButton(
            onPressed: () {
              refresh();
            },
            child: new Icon(
              Icons.refresh,
              color: Colors.blue,
              size: 30.0,
            ),
          )
        ],
      ),
    ];
    return PageView(
      controller: controller,
      children: pages,
    );
  }

  void refresh() async {
    setState(() {});
  }
}

class PageWithFutureBuilder extends StatefulWidget {
  PageWithFutureBuilder({Key key}) : super(key: key);
  @override
  State<StatefulWidget> createState() => _PageWithFutureBuilderState();
}

Future test() async {
  return;
}

class _PageWithFutureBuilderState extends State<PageWithFutureBuilder> {
  Future future;
  @override
  void initState() {
    future = test();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: future,
      builder: (ocntext, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting)
          return Container(
            color: Colors.black,
            child: Center(child: CircularProgressIndicator()),
          );
        else if (snapshot.connectionState == ConnectionState.done) {
          return Center(child: Text('test text'));
        } else
          return Container();
      },
    );
  }
}

滑动到第二页,然后点击按钮,你会看到闪烁。至于jumping back to page at index 0的代码,它们太复杂了,不能放在这里,这可能是与闪烁相同的原因。

EN

Stack Overflow用户

回答已采纳

发布于 2020-11-13 11:31:19

我想我找到了正确的解决方案。基本上这是由于使用了错误的Key造成的。使用UniqueKey会使Flutter将子窗口小部件视为不同,因此每次重新构建时都会重新初始化新的子窗口小部件。因此会闪烁并跳回到索引为0的页面。

不使用UniqueKey,而是使用value键。在我的例子中,我的每个子级父级都有一个惟一的键,所以我使用Key(objectID)作为object ID。因此,当SetState()被调用时,flutter将知道一些小部件可以重用,因为它们具有相同的键,所以闪烁消失了,它不会跳回索引为0的页面。

票数 3
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64802686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档