Commit 65caad47 authored by Hans Muller's avatar Hans Muller

Enable fling scrolling in TabBar

parent 2c09a982
......@@ -16,11 +16,12 @@ class TabbedNavigatorApp extends App {
// The index of the selected tab for each of the TabNavigators constructed below.
List<int> selectedIndices = new List<int>.filled(5, 0);
TabNavigator _buildTabNavigator(int n, List<TabNavigatorView> views, {scrollable: false}) {
TabNavigator _buildTabNavigator(int n, List<TabNavigatorView> views, Key key, {isScrollable: false}) {
return new TabNavigator(
key: key,
views: views,
selectedIndex: selectedIndices[n],
scrollable: scrollable,
isScrollable: isScrollable,
onChanged: (tabIndex) {
setState(() { selectedIndices[n] = tabIndex; } );
}
......@@ -41,7 +42,7 @@ class TabbedNavigatorApp extends App {
builder: () => _buildContent(text)
);
});
return _buildTabNavigator(n, views.toList());
return _buildTabNavigator(n, views.toList(), new Key('textLabelsTabNavigator'));
}
TabNavigator _buildIconLabelsTabNavigator(int n) {
......@@ -52,7 +53,7 @@ class TabbedNavigatorApp extends App {
builder: () => _buildContent(icon_name)
);
});
return _buildTabNavigator(n, views.toList());
return _buildTabNavigator(n, views.toList(), new Key('iconLabelsTabNavigator'));
}
TabNavigator _buildTextAndIconLabelsTabNavigator(int n) {
......@@ -70,7 +71,7 @@ class TabbedNavigatorApp extends App {
builder: () => _buildContent("Summary")
)
];
return _buildTabNavigator(n, views);
return _buildTabNavigator(n, views, new Key('textAndIconLabelsTabNavigator'));
}
TabNavigator _buildScrollableTabNavigator(int n) {
......@@ -80,7 +81,7 @@ class TabbedNavigatorApp extends App {
"THIS TAB IS PRETTY WIDE TOO",
"MORE",
"TABS",
"TO",
"TO",
"STRETCH",
"OUT",
"THE",
......@@ -92,7 +93,7 @@ class TabbedNavigatorApp extends App {
builder: () => _buildContent(text)
);
});
return _buildTabNavigator(n, views.toList(), scrollable: true);
return _buildTabNavigator(n, views.toList(), new Key('scrollableTabNavigator'), isScrollable: true);
}
......@@ -124,7 +125,7 @@ class TabbedNavigatorApp extends App {
)
];
TabNavigator tabNavigator = _buildTabNavigator(4, views);
TabNavigator tabNavigator = _buildTabNavigator(4, views, new Key('tabs'));
assert(selectedIndices.length == 5);
ToolBar toolbar = new ToolBar(
......
......@@ -60,7 +60,7 @@ class FlingBehavior extends BoundedBehavior {
: super(contentsSize: contentsSize, containerSize: containerSize);
Simulation release(double position, double velocity) {
return createDefaultScrollSimulation(position, 0.0, minScrollOffset, maxScrollOffset);
return createDefaultScrollSimulation(position, velocity, minScrollOffset, maxScrollOffset);
}
}
......
......@@ -4,6 +4,7 @@
import 'dart:math' as math;
import 'package:newton/newton.dart';
import 'package:sky/animation/scroll_behavior.dart';
import 'package:sky/painting/text_style.dart';
import 'package:sky/rendering/box.dart';
......@@ -32,7 +33,7 @@ const double _kRelativeMaxTabWidth = 56.0;
const EdgeDims _kTabLabelPadding = const EdgeDims.symmetric(horizontal: 12.0);
const TextStyle _kTabTextStyle = const TextStyle(textAlign: TextAlign.center);
const int _kTabIconSize = 24;
const double _kTabBarScrollFriction = 0.005;
const double _kTabBarScrollDrag = 0.025;
class TabBarParentData extends BoxParentData with
ContainerParentDataMixin<RenderBox> { }
......@@ -79,11 +80,11 @@ class RenderTabBar extends RenderBox with
}
}
bool _scrollable;
bool get scrollable => _scrollable;
void set scrollable(bool value) {
if (_scrollable != value) {
_scrollable = value;
bool _isScrollable;
bool get isScrollable => _isScrollable;
void set isScrollable(bool value) {
if (_isScrollable != value) {
_isScrollable = value;
markNeedsLayout();
}
}
......@@ -104,7 +105,7 @@ class RenderTabBar extends RenderBox with
assert(child.parentData is TabBarParentData);
child = child.parentData.nextSibling;
}
double width = scrollable ? maxWidth : maxWidth * childCount;
double width = isScrollable ? maxWidth : maxWidth * childCount;
return constraints.constrainWidth(width);
}
......@@ -119,7 +120,7 @@ class RenderTabBar extends RenderBox with
assert(child.parentData is TabBarParentData);
child = child.parentData.nextSibling;
}
double width = scrollable ? maxWidth : maxWidth * childCount;
double width = isScrollable ? maxWidth : maxWidth * childCount;
return constraints.constrainWidth(width);
}
......@@ -172,10 +173,10 @@ class RenderTabBar extends RenderBox with
void reportLayoutChangedIfNeeded() {
assert(onLayoutChanged != null);
List<double> widths = new List<double>(childCount);
if (!scrollable && childCount > 0) {
if (!isScrollable && childCount > 0) {
double tabWidth = size.width / childCount;
widths.fillRange(0, widths.length - 1, tabWidth);
} else if (scrollable) {
} else if (isScrollable) {
RenderBox child = firstChild;
int childIndex = 0;
while (child != null) {
......@@ -200,7 +201,7 @@ class RenderTabBar extends RenderBox with
if (childCount == 0)
return;
if (scrollable)
if (isScrollable)
layoutScrollableTabs();
else
layoutFixedWidthTabs();
......@@ -255,7 +256,7 @@ class TabBarWrapper extends MultiChildRenderObjectWrapper {
this.backgroundColor,
this.indicatorColor,
this.textAndIcons,
this.scrollable: false,
this.isScrollable: false,
this.onLayoutChanged
}) : super(key: key, children: children);
......@@ -263,7 +264,7 @@ class TabBarWrapper extends MultiChildRenderObjectWrapper {
final Color backgroundColor;
final Color indicatorColor;
final bool textAndIcons;
final bool scrollable;
final bool isScrollable;
final LayoutChanged onLayoutChanged;
RenderTabBar get root => super.root;
......@@ -275,7 +276,7 @@ class TabBarWrapper extends MultiChildRenderObjectWrapper {
root.backgroundColor = backgroundColor;
root.indicatorColor = indicatorColor;
root.textAndIcons = textAndIcons;
root.scrollable = scrollable;
root.isScrollable = isScrollable;
root.onLayoutChanged = onLayoutChanged;
}
}
......@@ -345,32 +346,54 @@ class Tab extends Component {
}
}
class _TabsScrollBehavior extends BoundedBehavior {
_TabsScrollBehavior({ double contentsSize: 0.0, double containerSize: 0.0 })
: super(contentsSize: contentsSize, containerSize: containerSize);
bool isScrollable = true;
Simulation release(double position, double velocity) {
if (!isScrollable)
return null;
double velocityPerSecond = velocity * 1000.0;
return new BoundedFrictionSimulation(
_kTabBarScrollDrag, position, velocityPerSecond, minScrollOffset, maxScrollOffset
);
}
double applyCurve(double scrollOffset, double scrollDelta) {
return (isScrollable) ? super.applyCurve(scrollOffset, scrollDelta) : 0.0;
}
}
class TabBar extends Scrollable {
TabBar({
Key key,
this.labels,
this.selectedIndex: 0,
this.onChanged,
this.scrollable: false
this.isScrollable: false
}) : super(key: key, direction: ScrollDirection.horizontal);
Iterable<TabLabel> labels;
int selectedIndex;
SelectedIndexChanged onChanged;
bool scrollable;
bool isScrollable;
void syncFields(TabBar source) {
super.syncFields(source);
labels = source.labels;
selectedIndex = source.selectedIndex;
onChanged = source.onChanged;
scrollable = source.scrollable;
if (!scrollable)
isScrollable = source.isScrollable;
if (!isScrollable)
scrollTo(0.0);
scrollBehavior.isScrollable = source.isScrollable;
}
ScrollBehavior createScrollBehavior() => new FlingBehavior();
FlingBehavior get scrollBehavior => super.scrollBehavior;
ScrollBehavior createScrollBehavior() => new _TabsScrollBehavior();
_TabsScrollBehavior get scrollBehavior => super.scrollBehavior;
void _handleTap(int tabIndex) {
if (tabIndex != selectedIndex && onChanged != null)
......@@ -445,8 +468,8 @@ class TabBar extends Scrollable {
backgroundColor: backgroundColor,
indicatorColor: indicatorColor,
textAndIcons: textAndIcons,
scrollable: scrollable,
onLayoutChanged: scrollable ? _layoutChanged : null
isScrollable: isScrollable,
onLayoutChanged: isScrollable ? _layoutChanged : null
)
)
)
......@@ -474,13 +497,13 @@ class TabNavigator extends Component {
this.views,
this.selectedIndex: 0,
this.onChanged,
this.scrollable: false
this.isScrollable: false
}) : super(key: key);
final List<TabNavigatorView> views;
final int selectedIndex;
final SelectedIndexChanged onChanged;
final bool scrollable;
final bool isScrollable;
void _handleSelectedIndexChanged(int tabIndex) {
if (onChanged != null)
......@@ -495,7 +518,7 @@ class TabNavigator extends Component {
labels: views.map((view) => view.label),
onChanged: _handleSelectedIndexChanged,
selectedIndex: selectedIndex,
scrollable: scrollable
isScrollable: isScrollable
);
Widget content = views[selectedIndex].buildContent();
......
......@@ -9,7 +9,7 @@ dependencies:
mojo_services: ^0.0.15
mojo: ^0.0.17
mojom: ^0.0.17
newton: ^0.1.0
newton: ^0.1.2
sky_engine: ^0.0.1
sky_services: ^0.0.1
sky_tools: ^0.0.4
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment