InheritedWidget中的GlobalKey导致重新父级

问题描述 投票:0回答:1

使用InheritedWidget和反模式将GlobalKey传递给树?每次重新构建其子树时,都会重新创建使用该密钥的有状态窗口小部件(即,这个initState /处置的新状态)。

我的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)通过DimensionScopedKeyProvider.of()传递给我的构建方法的GlobalKeys的hashCode总是相同的。

有状态的小部件构建类似于


GlobalKey<PanelScaffoldState> get _headerKey => //
  DimensionScopedKeyProvider.of(context).progressiveChatHeaderKey;

// ...

PanelScaffold(
  key: _headerKey,
  // ...
)

当我更改影响PanelScaffold所在的子树的属性时,会创建一个新的PanelScaffoldState并处理旧的_headerKey,即使小部件树没有更改结构且didChangeDependencies也没有改变。

flutter
1个回答
0
投票

我也能解决这个问题,但我不知道为什么会这样。

解决方案是在 @override void didChangeDependencies() { super.didChangeDependencies(); _headerKey ??= DimensionScopedKeyProvider.of(context).progressiveChatHeaderKey; } 中缓存对GlobalKey的访问

qazxswpoi

....现在一切都按预期工作 - 重建重新成为现有状态的父母。

有谁知道为什么缓存到GlobalKey的getter是关键?

© www.soinside.com 2019 - 2024. All rights reserved.