-
Notifications
You must be signed in to change notification settings - Fork 29.7k
SliverLayoutBuilder #35941
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
SliverLayoutBuilder #35941
Conversation
|
A thought I have after look at the pr, instead of doing the inherit structure, you can try to wrap Layoutbuilder by using SliverConstraints.asBoxConstraints to convert the constraints that passed down to builder and RenderSliverToBoxAdapter to convert the renderbox back to rendersliver. This should make it a SliverLayoutbuilder. |
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.
Overall looks good, I leave some minor comment.
I do not have enough background on this. Can you explain more how this can help we solve #23873? What are the obstacle we facing if we don't have SliverLayoutBuilder?
| void applyPaintTransform(RenderObject child, Matrix4 transform) { | ||
| assert(child != null); | ||
| assert(child == this.child); | ||
| // No-op because child's offset is always (0, 0), |
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.
We don't use the word 'no-op' in our documentation. maybe 'It does not require transformation because..."
| final RenderBox renderChild1 = tester.renderObject(find.byKey(childKey1)); | ||
| final RenderBox renderChild2 = tester.renderObject(find.byKey(childKey2)); | ||
|
|
||
| // scrollController.scrollOffset = 0: |
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.
end with dot
…tter into sliver-layoutbuilder
| typedef SliverLayoutWidgetBuilder = Widget Function(BuildContext context, SliverConstraints constraints); | ||
|
|
||
| // A widget that defers its building until layout. | ||
| abstract class _GenericLayoutBuilder<ConstraintType extends Constraints> extends RenderObjectWidget { |
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.
after talked with @dnfield offline, it feels strange that we have public class inherit from private class, let's make this class public. In that class, the build property can documented here instead of duplicated in two subclass.
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.
Perhaps this could be called ConstrainedLayoutBuilder
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.
Also exposed RenderConstrainedLayoutBuilder for subclassing. _LayoutBuilderElement should be generic enough to stay private.
dnfield
left a comment
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.
The parts I looked at LGTM, I'll defer to @chunhtai to finish the rest of his review
| if (child != null) | ||
| context.paintChild(child, offset); | ||
| } | ||
|
|
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 outsource the sliver stuff in a separate sliver_layout_builder.dart file?
| mixin RenderConstrainedLayoutBuilder<ConstraintType extends Constraints, ChildType extends RenderObject> on RenderObjectWithChildMixin<ChildType> { | ||
| LayoutCallback<ConstraintType> _callback; | ||
| /// Change the layout callback. | ||
| set callback(LayoutCallback<ConstraintType> value) { |
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.
Having a setter without a getter is strange...
| }) : super(key: key, builder: builder); | ||
|
|
||
| @override | ||
| LayoutWidgetBuilder get builder; |
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 I am missing something, but how does this override work? It doesn't have a body and the class is not marked abstract?
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.
Woah I didn't realize that and it passed the tests. Turns out this is expected, according to the language spec:
section: 16.19:
Let m be an identifier, o an object, L a library, and C a class which is the
class of o or a superclass thereof.
...
The result of a getter lookup for m in o with respect to L starting in class
C is the result of a getter lookup for m in C with respect to L. The result of a
getter lookup for m in C with respect to L is: If C declares a concrete instance
getter named m that is accessible to L, then that getter declaration is the result
of the getter lookup, and we say that the getter was looked up in C. Otherwise,
if C has a superclass S, the result of the getter lookup is the result of a getter
lookup for m in S with respect to L. Otherwise, we say that the getter lookup
has failed.
section 10.4:
The purpose of an abstract method is to provide a declaration for purposes
such as type checking and reflection. In mixins, it is often useful to introduce
such declarations for methods that the mixin expects will be provided by the
superclass the mixin is applied to.
We wish to detect if one declares a concrete class with abstract members.
However, code like the following should work:
class Base {
int get one => 1;
}
abstract class Mix {
int get one;
int get two => one + one;
}
class C extends Base with Mix { }
At run time, the concrete method one declared in Base will be executed, and
no problem should arise. Therefore no error should be raised if a corresponding
concrete member exists in the hierarchy.
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.
added implementation.
goderbauer
left a comment
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.
LGTM
| import 'debug.dart'; | ||
| import 'framework.dart'; | ||
|
|
||
| export 'sliver_layout_builder.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.
This export should probably be in flutter/lib/widgets.dart instead.
|
|
||
| @override | ||
| _RenderLayoutBuilder createRenderObject(BuildContext context) => _RenderLayoutBuilder(); | ||
| /// Called at layout time to construct the widget tree. The builder must not |
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.
nit: the first paragraph of a doc comment should be a one-sentence summary.
chunhtai
left a comment
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.
LGTM
| expect(parentSliver.geometry.scrollExtent, childHeight); | ||
| expect(parentSliver.geometry.paintExtent, childHeight); | ||
|
|
||
| // When child is over-sized. |
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.
half sentence
Description
SliverLayoutBuilder.Related Issues
Closes #35927
Tests
I added the following tests:
SliverLayoutBuilderversions of mostLayoutBuildertestsChecklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change
Does your PR require Flutter developers to manually update their apps to accommodate your change?