多个小部件使用相同的

多个小部件使用相同的

本文介绍了多个小部件使用相同的 GlobalKey的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Flutter.我有一个带有 3 个选项卡的简单应用程序.每个带有 ListView 的选项卡中都有一个 RefreshIndicator.这些行是用另一种方法构建的.这是代码:

I'm using Flutter. I have a simple app with 3 tabs. There is a RefreshIndicator in each tab with a ListView. The rows are built in another method.This is the code:

 @override
 Widget build(BuildContext context) {
    final GlobalKey<RefreshIndicatorState> _RIKey1 = new GlobalKey<RefreshIndicatorState>();
    final GlobalKey<RefreshIndicatorState> _RIKey2 = new GlobalKey<RefreshIndicatorState>();
    final GlobalKey<RefreshIndicatorState> _RIKey3 = new GlobalKey<RefreshIndicatorState>();

    debugPrint(_RIKey1.toString());
    debugPrint(_RIKey2.toString());
    debugPrint(_RIKey3.toString());
    return new Scaffold(
      body: new DefaultTabController(
        length: 3,
        child: new Scaffold(
          appBar: new AppBar(
            bottom: new TabBar(
              tabs: [
                new Tab(icon: new Icon(Icons.view_list)),
                new Tab(icon: new Icon(Icons.hotel)),
                new Tab(icon: new Icon(Icons.assessment)),
              ],
            ),
            title: new Text('Data'),
          ),
          body: new TabBarView(
            children: [
              new RefreshIndicator(
                key: _RIKey1,
                onRefresh: _actualizoData,
                child: new ListView.builder(
                    padding: new EdgeInsets.only(top: 5.0),
                    itemCount: linea_reservas.length * 2,
                    itemBuilder: (BuildContext context, int position) {
                      if (position.isOdd) return new Divider();
                      final index = position ~/ 2;
                      return _buildRow(index);
                    }),
              ),
              new RefreshIndicator(
                key: _RIKey2,
                onRefresh: _actualizoData,
                child: new ListView.builder(
                    padding: new EdgeInsets.only(top: 8.0),
                    itemCount: linea_inouthouse.length * 2,
                    itemBuilder: (BuildContext context, int position) {
                      if (position.isOdd) return new Divider();
                      final index = position ~/ 2;
                      return _buildRowInOutHouse(index);
                    }),
              ),
              new RefreshIndicator(
                key: _RIKey3,
                onRefresh: _actualizoData,
                child: new ListView.builder(
                    padding: new EdgeInsets.only(top: 5.0),
                    itemCount: linea_ocupacion.length * 2,
                    itemBuilder: (BuildContext context, int position) {
                      if (position.isOdd) return new Divider();
                      final index = position ~/ 2;
                      return _buildRowOcupacion(index);
                    }),
              ),
            ],
          ),
        ),
      ),
    );
  }

我添加了 debugPrints 并且输出是 6 行,而不是 3 行.

I'd added the debugPrints and the output are 6 lines, instead of 3.

I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#4d76c]
I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#59b9e]
I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#2c88b]
I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#7bd42]
I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#1c984]
I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#dbe20]

该应用程序可以运行,但在多次更改选项卡后,它会因以下错误而崩溃:

    I/flutter ( 5252): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 5252): The following assertion was thrown building NotificationListener<KeepAliveNotification>:
I/flutter ( 5252): Multiple widgets used the same GlobalKey.
I/flutter ( 5252): The key [LabeledGlobalKey<RefreshIndicatorState>#7bd42] was used by multiple widgets. The parents of
I/flutter ( 5252): those widgets were:
I/flutter ( 5252): - RepaintBoundary-[<[LabeledGlobalKey<RefreshIndicatorState>#7bd42]>](renderObject:
I/flutter ( 5252):   RenderRepaintBoundary#60a4a DETACHED)
I/flutter ( 5252): - RepaintBoundary-[<[LabeledGlobalKey<RefreshIndicatorState>#7bd42]>](renderObject:
I/flutter ( 5252):   RenderRepaintBoundary#c8cdb NEEDS-LAYOUT NEEDS-PAINT)
I/flutter ( 5252): A GlobalKey can only be specified on one widget at a time in the widget tree.

密钥是在Build方法中生成的,所以,我不明白为什么Multiple widgets using the same GlobalKey错误

The keys are generated in the Build method, so, I don't understand why the Multiple widgets used the same GlobalKey error

为什么会再次生成密钥,为什么不是唯一的?我不是在谈论一千个意图,在选项卡之间切换 4 或 5 次后会出现错误.感谢您的任何帮助.

Why the key is generated again, and why it's not unique? I'm not talking of a thousand intents, the error appears after changing between tabs 4 or 5 times.Thank you for any help.

推荐答案

您能否手动"创建密钥并使用静态/常量值?例如...

Could you create your keys "by hand" and use static/constant values? e.g. ...

import 'package:flutter/widgets.dart';

class RIKeys {
  static final riKey1 = const Key('__RIKEY1__');
  static final riKey2 = const Key('__RIKEY2__');
  static final riKey3 = const Key('__RIKEY3__');
}

然后在...

    body: new TabBarView(
            children: [
              new RefreshIndicator(new RefreshIndicator(
// Use the Manual Static Value instead ...
                key: RIKeys.riKey1,
                onRefresh: _actualizoData,
                child: new ListView.builder(
                    padding: new EdgeInsets.only(top: 5.0),
                    itemCount: linea_reservas.length * 2,
                    itemBuilder: (BuildContext context, int position) {
                      if (position.isOdd) return new Divider();
                      final index = position ~/ 2;
                      return _buildRow(index);
                    }),
              ),

我在类似的情况下做过这件事并取得了一些成功......尤其是使用 redux 或其他类似的模式......

I have done this in a similar situation with some success ... especially with redux or other similar patterns ...

这篇关于多个小部件使用相同的 GlobalKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 22:15