done
This commit is contained in:
parent
1867b58c40
commit
aaeaed9be8
@ -35,7 +35,6 @@ const double _kTextAndIconTabHeight = 72.0;
|
|||||||
const double _kTabIndicatorHeight = 2.0;
|
const double _kTabIndicatorHeight = 2.0;
|
||||||
const double _kMinTabWidth = 72.0;
|
const double _kMinTabWidth = 72.0;
|
||||||
const double _kMaxTabWidth = 264.0;
|
const double _kMaxTabWidth = 264.0;
|
||||||
const double _kRelativeMaxTabWidth = 56.0;
|
|
||||||
const EdgeDims _kTabLabelPadding = const EdgeDims.symmetric(horizontal: 12.0);
|
const EdgeDims _kTabLabelPadding = const EdgeDims.symmetric(horizontal: 12.0);
|
||||||
const int _kTabIconSize = 24;
|
const int _kTabIconSize = 24;
|
||||||
const double _kTabBarScrollDrag = 0.025;
|
const double _kTabBarScrollDrag = 0.025;
|
||||||
@ -139,9 +138,8 @@ class RenderTabBar extends RenderBox with
|
|||||||
return constraints.constrainWidth(width);
|
return constraints.constrainWidth(width);
|
||||||
}
|
}
|
||||||
|
|
||||||
double get _tabBarHeight {
|
double get _tabHeight => textAndIcons ? _kTextAndIconTabHeight : _kTabHeight;
|
||||||
return (textAndIcons ? _kTextAndIconTabHeight : _kTabHeight) + _kTabIndicatorHeight;
|
double get _tabBarHeight => _tabHeight + _kTabIndicatorHeight;
|
||||||
}
|
|
||||||
|
|
||||||
double _getIntrinsicHeight(BoxConstraints constraints) => constraints.constrainHeight(_tabBarHeight);
|
double _getIntrinsicHeight(BoxConstraints constraints) => constraints.constrainHeight(_tabBarHeight);
|
||||||
|
|
||||||
@ -152,7 +150,7 @@ class RenderTabBar extends RenderBox with
|
|||||||
void layoutFixedWidthTabs() {
|
void layoutFixedWidthTabs() {
|
||||||
double tabWidth = size.width / childCount;
|
double tabWidth = size.width / childCount;
|
||||||
BoxConstraints tabConstraints =
|
BoxConstraints tabConstraints =
|
||||||
new BoxConstraints.tightFor(width: tabWidth, height: size.height);
|
new BoxConstraints.tightFor(width: tabWidth, height: _tabHeight);
|
||||||
double x = 0.0;
|
double x = 0.0;
|
||||||
RenderBox child = firstChild;
|
RenderBox child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
@ -164,12 +162,13 @@ class RenderTabBar extends RenderBox with
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void layoutScrollableTabs() {
|
double layoutScrollableTabs() {
|
||||||
BoxConstraints tabConstraints = new BoxConstraints(
|
BoxConstraints tabConstraints = new BoxConstraints(
|
||||||
minWidth: _kMinTabWidth,
|
minWidth: _kMinTabWidth,
|
||||||
maxWidth: math.min(size.width - _kRelativeMaxTabWidth, _kMaxTabWidth),
|
maxWidth: _kMaxTabWidth,
|
||||||
minHeight: size.height,
|
minHeight: _tabHeight,
|
||||||
maxHeight: size.height);
|
maxHeight: _tabHeight
|
||||||
|
);
|
||||||
double x = 0.0;
|
double x = 0.0;
|
||||||
RenderBox child = firstChild;
|
RenderBox child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
@ -179,6 +178,7 @@ class RenderTabBar extends RenderBox with
|
|||||||
x += child.size.width;
|
x += child.size.width;
|
||||||
child = child.parentData.nextSibling;
|
child = child.parentData.nextSibling;
|
||||||
}
|
}
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
Size layoutSize;
|
Size layoutSize;
|
||||||
@ -209,17 +209,16 @@ class RenderTabBar extends RenderBox with
|
|||||||
|
|
||||||
void performLayout() {
|
void performLayout() {
|
||||||
assert(constraints is BoxConstraints);
|
assert(constraints is BoxConstraints);
|
||||||
|
|
||||||
size = constraints.constrain(new Size(constraints.maxWidth, _tabBarHeight));
|
|
||||||
assert(!size.isInfinite);
|
|
||||||
|
|
||||||
if (childCount == 0)
|
if (childCount == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (isScrollable)
|
if (isScrollable) {
|
||||||
layoutScrollableTabs();
|
double tabBarWidth = layoutScrollableTabs();
|
||||||
else
|
size = constraints.constrain(new Size(tabBarWidth, _tabBarHeight));
|
||||||
|
} else {
|
||||||
|
size = constraints.constrain(new Size(constraints.maxWidth, _tabBarHeight));
|
||||||
layoutFixedWidthTabs();
|
layoutFixedWidthTabs();
|
||||||
|
}
|
||||||
|
|
||||||
if (onLayoutChanged != null)
|
if (onLayoutChanged != null)
|
||||||
reportLayoutChangedIfNeeded();
|
reportLayoutChangedIfNeeded();
|
||||||
@ -234,7 +233,7 @@ class RenderTabBar extends RenderBox with
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (indicatorRect != null) {
|
if (indicatorRect != null) {
|
||||||
canvas.drawRect(indicatorRect, new Paint()..color = indicatorColor);
|
canvas.drawRect(indicatorRect.shift(offset), new Paint()..color = indicatorColor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,6 +403,7 @@ class TabBar extends Scrollable {
|
|||||||
bool isScrollable;
|
bool isScrollable;
|
||||||
|
|
||||||
Size _tabBarSize;
|
Size _tabBarSize;
|
||||||
|
Size _viewportSize = Size.zero;
|
||||||
List<double> _tabWidths;
|
List<double> _tabWidths;
|
||||||
ValueAnimation<Rect> _indicatorAnimation;
|
ValueAnimation<Rect> _indicatorAnimation;
|
||||||
|
|
||||||
@ -412,6 +412,7 @@ class TabBar extends Scrollable {
|
|||||||
_indicatorAnimation = new ValueAnimation<Rect>()
|
_indicatorAnimation = new ValueAnimation<Rect>()
|
||||||
..duration = _kTabBarScroll
|
..duration = _kTabBarScroll
|
||||||
..variable = new AnimatedRect(null, curve: ease);
|
..variable = new AnimatedRect(null, curve: ease);
|
||||||
|
scrollBehavior.isScrollable = isScrollable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncConstructorArguments(TabBar source) {
|
void syncConstructorArguments(TabBar source) {
|
||||||
@ -447,7 +448,7 @@ class TabBar extends Scrollable {
|
|||||||
if (tabIndex > 0)
|
if (tabIndex > 0)
|
||||||
tabLeft = _tabWidths.take(tabIndex).reduce((sum, width) => sum + width);
|
tabLeft = _tabWidths.take(tabIndex).reduce((sum, width) => sum + width);
|
||||||
double tabTop = 0.0;
|
double tabTop = 0.0;
|
||||||
double tabBottom = _tabBarSize.height -_kTabIndicatorHeight;
|
double tabBottom = _tabBarSize.height - _kTabIndicatorHeight;
|
||||||
double tabRight = tabLeft + _tabWidths[tabIndex];
|
double tabRight = tabLeft + _tabWidths[tabIndex];
|
||||||
return new Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
|
return new Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
|
||||||
}
|
}
|
||||||
@ -489,16 +490,26 @@ class TabBar extends Scrollable {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _updateScrollBehavior() {
|
||||||
|
scrollBehavior.updateExtents(
|
||||||
|
containerExtent: scrollDirection == ScrollDirection.vertical ? _viewportSize.height : _viewportSize.width,
|
||||||
|
contentExtent: _tabWidths.reduce((sum, width) => sum + width)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _layoutChanged(Size tabBarSize, List<double> tabWidths) {
|
void _layoutChanged(Size tabBarSize, List<double> tabWidths) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tabBarSize = tabBarSize;
|
_tabBarSize = tabBarSize;
|
||||||
_tabWidths = tabWidths;
|
_tabWidths = tabWidths;
|
||||||
scrollBehavior.updateExtents(
|
_updateScrollBehavior();
|
||||||
containerExtent: _tabBarSize.width,
|
|
||||||
contentExtent: _tabWidths.reduce((sum, width) => sum + width));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleViewportSizeChanged(Size newSize) {
|
||||||
|
_viewportSize = newSize;
|
||||||
|
_updateScrollBehavior();
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildContent() {
|
Widget buildContent() {
|
||||||
assert(labels != null && labels.isNotEmpty);
|
assert(labels != null && labels.isNotEmpty);
|
||||||
|
|
||||||
@ -531,35 +542,41 @@ class TabBar extends Scrollable {
|
|||||||
textAndIcons = true;
|
textAndIcons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4 transform = new Matrix4.identity();
|
Widget tabBar = new IconTheme(
|
||||||
transform.translate(-scrollOffset, 0.0);
|
data: new IconThemeData(color: iconThemeColor),
|
||||||
|
child: new DefaultTextStyle(
|
||||||
return new Transform(
|
style: textStyle,
|
||||||
transform: transform,
|
child: new BuilderTransition(
|
||||||
child: new IconTheme(
|
variables: [_indicatorRect],
|
||||||
data: new IconThemeData(color: iconThemeColor),
|
direction: Direction.forward,
|
||||||
child: new DefaultTextStyle(
|
performance: _indicatorAnimation,
|
||||||
style: textStyle,
|
builder: () {
|
||||||
child: new BuilderTransition(
|
return new TabBarWrapper(
|
||||||
variables: [_indicatorRect],
|
children: tabs,
|
||||||
direction: Direction.forward,
|
selectedIndex: selectedIndex,
|
||||||
performance: _indicatorAnimation,
|
backgroundColor: backgroundColor,
|
||||||
builder: () {
|
indicatorColor: indicatorColor,
|
||||||
return new TabBarWrapper(
|
indicatorRect: _indicatorRect.value,
|
||||||
children: tabs,
|
textAndIcons: textAndIcons,
|
||||||
selectedIndex: selectedIndex,
|
isScrollable: isScrollable,
|
||||||
backgroundColor: backgroundColor,
|
onLayoutChanged: _layoutChanged
|
||||||
indicatorColor: indicatorColor,
|
);
|
||||||
indicatorRect: _indicatorRect.value,
|
}
|
||||||
textAndIcons: textAndIcons,
|
|
||||||
isScrollable: isScrollable,
|
|
||||||
onLayoutChanged: _layoutChanged
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!isScrollable)
|
||||||
|
return tabBar;
|
||||||
|
|
||||||
|
return new SizeObserver(
|
||||||
|
callback: _handleViewportSizeChanged,
|
||||||
|
child: new Viewport(
|
||||||
|
scrollDirection: ScrollDirection.horizontal,
|
||||||
|
scrollOffset: new Offset(scrollOffset, 0.0),
|
||||||
|
child: tabBar
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user