-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Add widget inheritance links #6072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs please
|
Can you test what happens if you create a cycle (e.g., the child above the parent)? |
274f4a4 to
a577c02
Compare
|
I've added asserts, docs, and more tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally these classes would be outside the framework.dart file. Is that possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I've moved them into widgets/inherited_link.dart
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GlobalKey key?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and oops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would be redundant with the aforementioned change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use is! rather than !( is )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar comments here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this if block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in fact in general you should see if this function needs updating; markNeedsBuild changed a bit recently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow this is quite expensive. is there no quicker way to do this?
|
I suspect this doesn't work with LayoutBuilders. You should make sure you have tests where you have a layout builder and you change nothing (i.e. widgets are == across pumps) except that the layout builder is dirtied and something that would be inherited is dirtied, with situations like Note that in these cases, the |
|
another couple of things to test: ...where the root and link child do get rebuilt (because you provide new, albeit unchanged, widgets in the second pump). |
ad7c7ce to
5eaa842
Compare
5eaa842 to
3801dc2
Compare
| return new InkWell( | ||
| onTap: () { showButtonMenu(context); }, | ||
| child: config.child | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you could assert that button is not null.
| } | ||
| } | ||
|
|
||
| /// An element that uses a [InheritedWidgetLinkParent] as its configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'a' -> 'an'
| @override | ||
| InheritedWidgetLinkParent get widget => super.widget; | ||
|
|
||
| InheritedElementLinkChild get link => widget.link?._currentElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need docs?
| final Element linkElement = widget.link?._currentElement; | ||
| if (linkElement != null && linkElement is! InheritedElementLinkChild) { | ||
| throw new FlutterError( | ||
| 'InheritedWidgetLinkParent link value is not an InheritedWidgetLinkChild.\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can print the runtime type in the error.
| @override | ||
| InheritedWidgetLinkChildProxy get widget => super.widget; | ||
|
|
||
| InheritedElementLinkParent get link => widget.link?._currentElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs?
| final Element linkElement = widget.link?._currentElement; | ||
| if (linkElement != null && linkElement is! InheritedElementLinkParent) { | ||
| throw new FlutterError( | ||
| 'InheritedWidgetLinkChild link value is not an InheritedWidgetLinkParent.\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Runtime type here as well.
|
The last version of this code passed all of the proposed tests (and then some) except: In this case both halves of the link are built at layout time and the child is built first. That fails of course, because the child's parent and the values it's supposed to inherit aren't available. It's not possible to defer building the child until the parent has been built, since layout allocates sizes top-down. The link child's implementation could report a zero size and notify the link parent that when it was laid out it should mark the child as needing to be rebuilt. This would cause the entire tree to be built again. Additional links could cause even more rebuilding which would kill performance. The general purpose inheritance link is also flawed because in most cases one does not want the link child to inherit all of the link parent's inherited widgets. For example it would be a mistake to pick up the parent's TickerMode. |
Enable a widget to inherit from a widget that's not its parent.
The widget contained by an InheritedWidgetLinkChild inherits from the ancestors of the InheritedWidgetLinkParent that it is linked to.
The link itself is bi-directional and must be defined in terms of global keys. The value of the InheritedWidgetLinkParent's link is the InheritedWidgetLinkChild's global key, and vice versa.
The inheritance link is exlusive: the InheritedWidgetLinkChild only inherits from the InheritedWidgetLinkParent's ancestors, it no longer inherits from its own ancestors.
The value of the link may be null, which restores normal inherited widget behavior.
Fixes #5572