mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Animation Demo performance tweaks (#8586)
This commit is contained in:
parent
d5b502bbc2
commit
44dbecc6be
@ -161,12 +161,14 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
// until they're all visible.
|
// until they're all visible.
|
||||||
class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
||||||
_AllSectionsLayout({
|
_AllSectionsLayout({
|
||||||
|
this.translation,
|
||||||
this.tColumnToRow,
|
this.tColumnToRow,
|
||||||
this.tCollapsed,
|
this.tCollapsed,
|
||||||
this.cardCount,
|
this.cardCount,
|
||||||
this.selectedIndex,
|
this.selectedIndex,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final FractionalOffset translation;
|
||||||
final double tColumnToRow;
|
final double tColumnToRow;
|
||||||
final double tCollapsed;
|
final double tCollapsed;
|
||||||
final int cardCount;
|
final int cardCount;
|
||||||
@ -186,6 +188,7 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
|||||||
final double columnCardWidth = size.width - columnCardX;
|
final double columnCardWidth = size.width - columnCardX;
|
||||||
final double columnCardHeight = size.height / cardCount;
|
final double columnCardHeight = size.height / cardCount;
|
||||||
final double rowCardWidth = size.width;
|
final double rowCardWidth = size.width;
|
||||||
|
final Offset offset = translation.alongSize(size);
|
||||||
double columnCardY = 0.0;
|
double columnCardY = 0.0;
|
||||||
double rowCardX = -(selectedIndex * rowCardWidth);
|
double rowCardX = -(selectedIndex * rowCardWidth);
|
||||||
|
|
||||||
@ -209,7 +212,7 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
|||||||
// Layout the card for index.
|
// Layout the card for index.
|
||||||
final Rect columnCardRect = new Rect.fromLTWH(columnCardX, columnCardY, columnCardWidth, columnCardHeight);
|
final Rect columnCardRect = new Rect.fromLTWH(columnCardX, columnCardY, columnCardWidth, columnCardHeight);
|
||||||
final Rect rowCardRect = new Rect.fromLTWH(rowCardX, 0.0, rowCardWidth, size.height);
|
final Rect rowCardRect = new Rect.fromLTWH(rowCardX, 0.0, rowCardWidth, size.height);
|
||||||
final Rect cardRect = _interpolateRect(columnCardRect, rowCardRect);
|
final Rect cardRect = _interpolateRect(columnCardRect, rowCardRect).shift(offset);
|
||||||
final String cardId = 'card$index';
|
final String cardId = 'card$index';
|
||||||
if (hasChild(cardId)) {
|
if (hasChild(cardId)) {
|
||||||
// Add a small horizontal gap between the cards.
|
// Add a small horizontal gap between the cards.
|
||||||
@ -228,7 +231,7 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
|||||||
final Point columnTitleOrigin = new Point(columnTitleX, columnTitleY);
|
final Point columnTitleOrigin = new Point(columnTitleX, columnTitleY);
|
||||||
final Point rowTitleOrigin = new Point(centeredRowTitleX, rowTitleY);
|
final Point rowTitleOrigin = new Point(centeredRowTitleX, rowTitleY);
|
||||||
final Point titleOrigin = _interpolatePoint(columnTitleOrigin, rowTitleOrigin);
|
final Point titleOrigin = _interpolatePoint(columnTitleOrigin, rowTitleOrigin);
|
||||||
positionChild('title$index', titleOrigin.toOffset());
|
positionChild('title$index', titleOrigin.toOffset() + offset);
|
||||||
|
|
||||||
// Layout the selection indicator for index.
|
// Layout the selection indicator for index.
|
||||||
final Size indicatorSize = layoutChild('indicator$index', new BoxConstraints.loose(cardRect.size));
|
final Size indicatorSize = layoutChild('indicator$index', new BoxConstraints.loose(cardRect.size));
|
||||||
@ -240,7 +243,7 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
|||||||
final double rowIndicatorY = titleRect.bottomCenter.y + 16.0;
|
final double rowIndicatorY = titleRect.bottomCenter.y + 16.0;
|
||||||
final Point rowIndicatorOrigin = new Point(centeredRowIndicatorX, rowIndicatorY);
|
final Point rowIndicatorOrigin = new Point(centeredRowIndicatorX, rowIndicatorY);
|
||||||
final Point indicatorOrigin = _interpolatePoint(columnIndicatorOrigin, rowIndicatorOrigin);
|
final Point indicatorOrigin = _interpolatePoint(columnIndicatorOrigin, rowIndicatorOrigin);
|
||||||
positionChild('indicator$index', indicatorOrigin.toOffset());
|
positionChild('indicator$index', indicatorOrigin.toOffset() + offset);
|
||||||
|
|
||||||
columnCardY += columnCardHeight;
|
columnCardY += columnCardHeight;
|
||||||
rowCardX += rowCardWidth;
|
rowCardX += rowCardWidth;
|
||||||
@ -257,31 +260,35 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AllSectionsView extends StatelessWidget {
|
class _AllSectionsView extends AnimatedWidget {
|
||||||
_AllSectionsView({
|
_AllSectionsView({
|
||||||
Key key,
|
Key key,
|
||||||
|
this.sectionIndex,
|
||||||
this.sections,
|
this.sections,
|
||||||
this.selectedIndex,
|
this.selectedIndex,
|
||||||
this.minHeight,
|
this.minHeight,
|
||||||
this.midHeight,
|
this.midHeight,
|
||||||
this.maxHeight,
|
this.maxHeight,
|
||||||
this.sectionCards: const <Widget>[],
|
this.sectionCards: const <Widget>[],
|
||||||
}) : super(key: key) {
|
}) : super(key: key, listenable: selectedIndex) {
|
||||||
assert(sections != null);
|
assert(sections != null);
|
||||||
assert(sectionCards != null);
|
assert(sectionCards != null);
|
||||||
assert(sectionCards.length == sections.length);
|
assert(sectionCards.length == sections.length);
|
||||||
assert(selectedIndex >= 0.0 && selectedIndex < sections.length.toDouble());
|
assert(sectionIndex >= 0 && sectionIndex < sections.length);
|
||||||
|
assert(selectedIndex != null);
|
||||||
|
assert(selectedIndex.value >= 0.0 && selectedIndex.value < sections.length.toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int sectionIndex;
|
||||||
final List<Section> sections;
|
final List<Section> sections;
|
||||||
final double selectedIndex;
|
final ValueNotifier<double> selectedIndex;
|
||||||
final double minHeight;
|
final double minHeight;
|
||||||
final double midHeight;
|
final double midHeight;
|
||||||
final double maxHeight;
|
final double maxHeight;
|
||||||
final List<Widget> sectionCards;
|
final List<Widget> sectionCards;
|
||||||
|
|
||||||
double _selectedIndexDelta(int index) {
|
double _selectedIndexDelta(int index) {
|
||||||
return (index.toDouble() - selectedIndex).abs().clamp(0.0, 1.0);
|
return (index.toDouble() - selectedIndex.value).abs().clamp(0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _build(BuildContext context, BoxConstraints constraints) {
|
Widget _build(BuildContext context, BoxConstraints constraints) {
|
||||||
@ -342,10 +349,11 @@ class _AllSectionsView extends StatelessWidget {
|
|||||||
|
|
||||||
return new CustomMultiChildLayout(
|
return new CustomMultiChildLayout(
|
||||||
delegate: new _AllSectionsLayout(
|
delegate: new _AllSectionsLayout(
|
||||||
|
translation: new FractionalOffset(selectedIndex.value - sectionIndex, 0.0),
|
||||||
tColumnToRow: tColumnToRow,
|
tColumnToRow: tColumnToRow,
|
||||||
tCollapsed: tCollapsed,
|
tCollapsed: tCollapsed,
|
||||||
cardCount: sections.length,
|
cardCount: sections.length,
|
||||||
selectedIndex: selectedIndex,
|
selectedIndex: selectedIndex.value,
|
||||||
),
|
),
|
||||||
children: children,
|
children: children,
|
||||||
);
|
);
|
||||||
@ -370,7 +378,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
|
|||||||
final ScrollController _scrollController = new ScrollController();
|
final ScrollController _scrollController = new ScrollController();
|
||||||
final PageController _headingPageController = new PageController();
|
final PageController _headingPageController = new PageController();
|
||||||
final PageController _detailsPageController = new PageController();
|
final PageController _detailsPageController = new PageController();
|
||||||
double _selectedIndex = 0.0;
|
ValueNotifier<double> selectedIndex = new ValueNotifier<double>(0.0);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -401,9 +409,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
|
|||||||
|
|
||||||
bool _handlePageNotification(ScrollNotification notification, PageController leader, PageController follower) {
|
bool _handlePageNotification(ScrollNotification notification, PageController leader, PageController follower) {
|
||||||
if (notification.depth == 0 && notification is ScrollUpdateNotification) {
|
if (notification.depth == 0 && notification is ScrollUpdateNotification) {
|
||||||
setState(() {
|
selectedIndex.value = leader.page;
|
||||||
_selectedIndex = leader.page;
|
|
||||||
});
|
|
||||||
if (follower.page != leader.page)
|
if (follower.page != leader.page)
|
||||||
follower.position.jumpTo(leader.position.pixels, settle: false);
|
follower.position.jumpTo(leader.position.pixels, settle: false);
|
||||||
}
|
}
|
||||||
@ -441,17 +447,15 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
|
|||||||
for (int index = 0; index < allSections.length; index++) {
|
for (int index = 0; index < allSections.length; index++) {
|
||||||
headings.add(new Container(
|
headings.add(new Container(
|
||||||
decoration: new BoxDecoration(backgroundColor: _kAppBackgroundColor),
|
decoration: new BoxDecoration(backgroundColor: _kAppBackgroundColor),
|
||||||
child: new FractionalTranslation(
|
child: new ClipRect(
|
||||||
translation: new FractionalOffset(_selectedIndex - index, 0.0),
|
child: new _AllSectionsView(
|
||||||
child: new ClipRect(
|
sectionIndex: index,
|
||||||
child: new _AllSectionsView(
|
sections: allSections,
|
||||||
sections: allSections,
|
selectedIndex: selectedIndex,
|
||||||
selectedIndex: _selectedIndex,
|
minHeight: _kAppBarMinHeight,
|
||||||
minHeight: _kAppBarMinHeight,
|
midHeight: _kAppBarMidHeight,
|
||||||
midHeight: _kAppBarMidHeight,
|
maxHeight: maxHeight,
|
||||||
maxHeight: maxHeight,
|
sectionCards: sectionCards,
|
||||||
sectionCards: sectionCards,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -178,4 +178,7 @@ class ValueNotifier<T> extends ChangeNotifier {
|
|||||||
_value = newValue;
|
_value = newValue;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => '<$runtimeType>(value: $value)';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user