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.
|
||||
class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
||||
_AllSectionsLayout({
|
||||
this.translation,
|
||||
this.tColumnToRow,
|
||||
this.tCollapsed,
|
||||
this.cardCount,
|
||||
this.selectedIndex,
|
||||
});
|
||||
|
||||
final FractionalOffset translation;
|
||||
final double tColumnToRow;
|
||||
final double tCollapsed;
|
||||
final int cardCount;
|
||||
@ -186,6 +188,7 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
||||
final double columnCardWidth = size.width - columnCardX;
|
||||
final double columnCardHeight = size.height / cardCount;
|
||||
final double rowCardWidth = size.width;
|
||||
final Offset offset = translation.alongSize(size);
|
||||
double columnCardY = 0.0;
|
||||
double rowCardX = -(selectedIndex * rowCardWidth);
|
||||
|
||||
@ -209,7 +212,7 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
||||
// Layout the card for index.
|
||||
final Rect columnCardRect = new Rect.fromLTWH(columnCardX, columnCardY, columnCardWidth, columnCardHeight);
|
||||
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';
|
||||
if (hasChild(cardId)) {
|
||||
// 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 rowTitleOrigin = new Point(centeredRowTitleX, rowTitleY);
|
||||
final Point titleOrigin = _interpolatePoint(columnTitleOrigin, rowTitleOrigin);
|
||||
positionChild('title$index', titleOrigin.toOffset());
|
||||
positionChild('title$index', titleOrigin.toOffset() + offset);
|
||||
|
||||
// Layout the selection indicator for index.
|
||||
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 Point rowIndicatorOrigin = new Point(centeredRowIndicatorX, rowIndicatorY);
|
||||
final Point indicatorOrigin = _interpolatePoint(columnIndicatorOrigin, rowIndicatorOrigin);
|
||||
positionChild('indicator$index', indicatorOrigin.toOffset());
|
||||
positionChild('indicator$index', indicatorOrigin.toOffset() + offset);
|
||||
|
||||
columnCardY += columnCardHeight;
|
||||
rowCardX += rowCardWidth;
|
||||
@ -257,31 +260,35 @@ class _AllSectionsLayout extends MultiChildLayoutDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
class _AllSectionsView extends StatelessWidget {
|
||||
class _AllSectionsView extends AnimatedWidget {
|
||||
_AllSectionsView({
|
||||
Key key,
|
||||
this.sectionIndex,
|
||||
this.sections,
|
||||
this.selectedIndex,
|
||||
this.minHeight,
|
||||
this.midHeight,
|
||||
this.maxHeight,
|
||||
this.sectionCards: const <Widget>[],
|
||||
}) : super(key: key) {
|
||||
}) : super(key: key, listenable: selectedIndex) {
|
||||
assert(sections != null);
|
||||
assert(sectionCards != null);
|
||||
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 double selectedIndex;
|
||||
final ValueNotifier<double> selectedIndex;
|
||||
final double minHeight;
|
||||
final double midHeight;
|
||||
final double maxHeight;
|
||||
final List<Widget> sectionCards;
|
||||
|
||||
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) {
|
||||
@ -342,10 +349,11 @@ class _AllSectionsView extends StatelessWidget {
|
||||
|
||||
return new CustomMultiChildLayout(
|
||||
delegate: new _AllSectionsLayout(
|
||||
translation: new FractionalOffset(selectedIndex.value - sectionIndex, 0.0),
|
||||
tColumnToRow: tColumnToRow,
|
||||
tCollapsed: tCollapsed,
|
||||
cardCount: sections.length,
|
||||
selectedIndex: selectedIndex,
|
||||
selectedIndex: selectedIndex.value,
|
||||
),
|
||||
children: children,
|
||||
);
|
||||
@ -370,7 +378,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
|
||||
final ScrollController _scrollController = new ScrollController();
|
||||
final PageController _headingPageController = new PageController();
|
||||
final PageController _detailsPageController = new PageController();
|
||||
double _selectedIndex = 0.0;
|
||||
ValueNotifier<double> selectedIndex = new ValueNotifier<double>(0.0);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -401,9 +409,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
|
||||
|
||||
bool _handlePageNotification(ScrollNotification notification, PageController leader, PageController follower) {
|
||||
if (notification.depth == 0 && notification is ScrollUpdateNotification) {
|
||||
setState(() {
|
||||
_selectedIndex = leader.page;
|
||||
});
|
||||
selectedIndex.value = leader.page;
|
||||
if (follower.page != leader.page)
|
||||
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++) {
|
||||
headings.add(new Container(
|
||||
decoration: new BoxDecoration(backgroundColor: _kAppBackgroundColor),
|
||||
child: new FractionalTranslation(
|
||||
translation: new FractionalOffset(_selectedIndex - index, 0.0),
|
||||
child: new ClipRect(
|
||||
child: new _AllSectionsView(
|
||||
sections: allSections,
|
||||
selectedIndex: _selectedIndex,
|
||||
minHeight: _kAppBarMinHeight,
|
||||
midHeight: _kAppBarMidHeight,
|
||||
maxHeight: maxHeight,
|
||||
sectionCards: sectionCards,
|
||||
),
|
||||
child: new ClipRect(
|
||||
child: new _AllSectionsView(
|
||||
sectionIndex: index,
|
||||
sections: allSections,
|
||||
selectedIndex: selectedIndex,
|
||||
minHeight: _kAppBarMinHeight,
|
||||
midHeight: _kAppBarMidHeight,
|
||||
maxHeight: maxHeight,
|
||||
sectionCards: sectionCards,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -178,4 +178,7 @@ class ValueNotifier<T> extends ChangeNotifier {
|
||||
_value = newValue;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => '<$runtimeType>(value: $value)';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user