InheritedWidget中的GlobalKey导致重新父项

时间:2019-02-28 17:12:53

标签: flutter

使用InheritedWidget将GlobalKey传递到树上是反模式吗?每当重建其子树时,都会使用该键重新创建有状态的小部件(即,此initState / dispose的新状态)。

我的InheritedWidget看起来像:

import 'package:flutter/material.dart';

import '../widgets/carousel.dart';
import '../widgets/panel/panel.dart';

class _CarouselKey extends GlobalObjectKey<CarouselState> {
  const _CarouselKey(Object value) : super(value);
}

class _ProgressiveChatHeaderKey extends GlobalObjectKey<PanelScaffoldState> {
  const _ProgressiveChatHeaderKey(Object value) : super(value);
}

class DimensionScopedKeyProvider extends InheritedWidget {
  final _CarouselKey parallelBubbleCarouselKey;
  final _ProgressiveChatHeaderKey progressiveChatHeaderKey;

  final String keyString;

  DimensionScopedKeyProvider({
    Key key,
    @required this.keyString,
    @required Widget child,
  })  : parallelBubbleCarouselKey = _CarouselKey(keyString),
        progressiveChatHeaderKey = _ProgressiveChatHeaderKey(keyString),
        super(key: key, child: child);

  static DimensionScopedKeyProvider of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(DimensionScopedKeyProvider)
        as DimensionScopedKeyProvider);
  }

  @override
  bool updateShouldNotify(DimensionScopedKeyProvider oldWidget) => oldWidget.keyString != keyString;
}

并且此InheritedWidget用常量keyString呈现,这意味着1)updateShouldNotify总是返回false和2)通过{{1传递给我的构建方法的GlobalKeys的hashCode }}始终相同。

有状态的小部件构建类似

DimensionScopedKeyProvider.of()

但是,当我更改影响 GlobalKey<PanelScaffoldState> get _headerKey => // DimensionScopedKeyProvider.of(context).progressiveChatHeaderKey; // ... PanelScaffold( key: _headerKey, // ... ) 所在子树的属性时,即使小部件树没有更改结构,也会创建一个新的PanelScaffold并处置旧的树并且PanelScaffoldState也没有更改。

1 个答案:

答案 0 :(得分:0)

我也能够解决此问题,但我不知道为什么会起作用

解决方案是将对GlobalKey的访问缓存在didChangeDependencies

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _headerKey ??= DimensionScopedKeyProvider.of(context).progressiveChatHeaderKey;
  }

....现在一切都再次按预期运行-重建重新建立了现有状态的父级。

有人知道为什么将getter缓存到GlobalKey是这里的关键吗?