{"action":"created","comment":{"url":"https://api.github.com/repos/flutter/flutter/pulls/comments/95244355","pull_request_review_id":15793627,"id":95244355,"diff_hunk":"@@ -760,543 +352,478 @@ class TabBar<T> extends Scrollable implements AppBarBottomWidget {\n   /// the color of the theme's body2 text color is used.\n   final Color labelColor;\n \n-  /// The height of the tab labels and indicator.\n   @override\n   double get bottomHeight {\n-    for (TabLabel label in labels.values) {\n-      if (label.hasText && label.hasIcon)\n-        return _kTextAndIconTabHeight + _kTabIndicatorHeight;\n+    for (Widget widget in tabs) {\n+      if (widget is Tab) {\n+        final Tab tab = widget;\n+        if (tab.text != null && tab.icon != null)\n+          return _kTextAndIconTabHeight + _kTabIndicatorHeight;\n+      }\n     }\n     return _kTabHeight + _kTabIndicatorHeight;\n   }\n \n   @override\n-  _TabBarState<T> createState() => new _TabBarState<T>();\n+  _TabBarState createState() => new _TabBarState();\n }\n \n-class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelectionAnimationListener {\n-  TabBarSelectionState<T> _selection;\n-  bool _valueIsChanging = false;\n-  int _lastSelectedIndex = -1;\n+class _TabBarState extends State<TabBar> {\n+  final GlobalKey<ScrollableState> viewportKey = new GlobalKey<ScrollableState>();\n \n-  void _initSelection(TabBarSelectionState<T> newSelection) {\n-    if (_selection == newSelection)\n-      return;\n-    _selection?.removeAnimationListener(this);\n-    _selection = newSelection;\n-    _selection?.addAnimationListener(this);\n-    if (_selection != null)\n-      _lastSelectedIndex = _selection.index;\n-  }\n+  TabController _controller;\n+  _ChangeAnimation _changeAnimation;\n+  _IndicatorPainter _indicatorPainter;\n+  int _currentIndex;\n \n-  @override\n-  void didUpdateConfig(TabBar<T> oldConfig) {\n-    super.didUpdateConfig(oldConfig);\n-    if (config.isScrollable != oldConfig.isScrollable) {\n-      scrollBehavior.isScrollable = config.isScrollable;\n-      if (!config.isScrollable)\n-        scrollTo(0.0);\n+  void _initTabController() {\n+    if (_controller != null)\n+      _controller.animation.removeListener(_handleTick);\n+    _controller = config.controller ?? DefaultTabController.of(context);","path":"packages/flutter/lib/src/material/tabs.dart","position":1031,"original_position":1031,"commit_id":"e09a328b7bfc996995030f5aba439d8107eeeef6","original_commit_id":"e09a328b7bfc996995030f5aba439d8107eeeef6","user":{"login":"HansMuller","id":1377460,"avatar_url":"https://avatars.githubusercontent.com/u/1377460?v=3","gravatar_id":"","url":"https://api.github.com/users/HansMuller","html_url":"https://github.com/HansMuller","followers_url":"https://api.github.com/users/HansMuller/followers","following_url":"https://api.github.com/users/HansMuller/following{/other_user}","gists_url":"https://api.github.com/users/HansMuller/gists{/gist_id}","starred_url":"https://api.github.com/users/HansMuller/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HansMuller/subscriptions","organizations_url":"https://api.github.com/users/HansMuller/orgs","repos_url":"https://api.github.com/users/HansMuller/repos","events_url":"https://api.github.com/users/HansMuller/events{/privacy}","received_events_url":"https://api.github.com/users/HansMuller/received_events","type":"User","site_admin":false},"body":"Good point, done.","created_at":"2017-01-09T20:58:12Z","updated_at":"2017-01-09T20:58:12Z","html_url":"https://github.com/flutter/flutter/pull/7387#discussion_r95244355","pull_request_url":"https://api.github.com/repos/flutter/flutter/pulls/7387","_links":{"self":{"href":"https://api.github.com/repos/flutter/flutter/pulls/comments/95244355"},"html":{"href":"https://github.com/flutter/flutter/pull/7387#discussion_r95244355"},"pull_request":{"href":"https://api.github.com/repos/flutter/flutter/pulls/7387"}}},"pull_request":{"url":"https://api.github.com/repos/flutter/flutter/pulls/7387","id":100547057,"html_url":"https://github.com/flutter/flutter/pull/7387","diff_url":"https://github.com/flutter/flutter/pull/7387.diff","patch_url":"https://github.com/flutter/flutter/pull/7387.patch","issue_url":"https://api.github.com/repos/flutter/flutter/issues/7387","number":7387,"state":"open","locked":false,"title":"New Tabs API","user":{"login":"HansMuller","id":1377460,"avatar_url":"https://avatars.githubusercontent.com/u/1377460?v=3","gravatar_id":"","url":"https://api.github.com/users/HansMuller","html_url":"https://github.com/HansMuller","followers_url":"https://api.github.com/users/HansMuller/followers","following_url":"https://api.github.com/users/HansMuller/following{/other_user}","gists_url":"https://api.github.com/users/HansMuller/gists{/gist_id}","starred_url":"https://api.github.com/users/HansMuller/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HansMuller/subscriptions","organizations_url":"https://api.github.com/users/HansMuller/orgs","repos_url":"https://api.github.com/users/HansMuller/repos","events_url":"https://api.github.com/users/HansMuller/events{/privacy}","received_events_url":"https://api.github.com/users/HansMuller/received_events","type":"User","site_admin":false},"body":"This is a new version of the material Tabs classes. It's more flexible, a little more capable, and the implementation is about 15% smaller and 100% less crazy than the original.\r\n\r\nThe only new visual feature is that dragging the tab bar's view scrolls the tab bar to keep the selected tab centered. This feature is evident in all of the native android scrollable tab bars I've looked at.\r\n\r\nInstead of the TabBarSelection widget there is a TabController object that exposes the selected tab's index and an animation that changes when scrolling is going on. An instance of the TabController must be provided to the app's TabBar and TabBarView, which is easy enough for a stateful app. Alternatively one can be shared using the DefaultTabController inherited widget.\r\n\r\nHere's a simple example of DefaultTabController, TabBar, and TabBarView:\r\n\r\n```\r\n  Widget build(BuildContext context) {\r\n    return new DefaultTabController(\r\n      length: allPages.length,\r\n      child: new Scaffold(\r\n        appBar: new AppBar(\r\n          title: new Text('Current tabs API'),\r\n          tabBar: new TabBar(\r\n            tabs: allPages.map((Page page) => new Tab(text: page.label)),\r\n          )\r\n        ),\r\n        body: new TabBarView(\r\n          children: allPages.map((Page page) => new PageViewer(page)),\r\n        ),\r\n      ),\r\n    );\r\n  }\r\n\r\n// classes and values provided by the app...\r\n\r\nclass Page {\r\n  Page({ this.label });\r\n  final String label;\r\n  // .. other per page data here\r\n}\r\n\r\nfinal List<Page> allPages = <Page>[\r\n  // .. all the pages here\r\n];\r\n\r\nclass PageViewer extends StatelessWidget {\r\n  PageViewer({ Key key, this.page }) : super(key: key);\r\n  final Page page;\r\n  // ... a build function that displays one page\r\n}\r\n\r\n```\r\n\r\nSummary of the main API changes:\r\n\r\n- TabBarSelection is gone. TabController and DefaultTabController serve the same purpose.\r\n- TabLabel is gone. The Tab widget displays a text/icon label and the Tab's icon itself is just a widget.\r\n- TabBar and TabBarView now longer have type parameters. All of the tabs components are configured in terms of the selected tab index and the tab list \"length\".\r\n- TabBar's tabs are just a list of Widgets (typically Tab widgets), rather than a Map<T, TabLabel>.\r\n","created_at":"2017-01-07T00:05:41Z","updated_at":"2017-01-09T20:58:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c11e871873616bae1f5dfb932cc8beb881f23611","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/flutter/flutter/pulls/7387/commits","review_comments_url":"https://api.github.com/repos/flutter/flutter/pulls/7387/comments","review_comment_url":"https://api.github.com/repos/flutter/flutter/pulls/comments{/number}","comments_url":"https://api.github.com/repos/flutter/flutter/issues/7387/comments","statuses_url":"https://api.github.com/repos/flutter/flutter/statuses/e09a328b7bfc996995030f5aba439d8107eeeef6","head":{"label":"HansMuller:new_new_tabs","ref":"new_new_tabs","sha":"e09a328b7bfc996995030f5aba439d8107eeeef6","user":{"login":"HansMuller","id":1377460,"avatar_url":"https://avatars.githubusercontent.com/u/1377460?v=3","gravatar_id":"","url":"https://api.github.com/users/HansMuller","html_url":"https://github.com/HansMuller","followers_url":"https://api.github.com/users/HansMuller/followers","following_url":"https://api.github.com/users/HansMuller/following{/other_user}","gists_url":"https://api.github.com/users/HansMuller/gists{/gist_id}","starred_url":"https://api.github.com/users/HansMuller/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HansMuller/subscriptions","organizations_url":"https://api.github.com/users/HansMuller/orgs","repos_url":"https://api.github.com/users/HansMuller/repos","events_url":"https://api.github.com/users/HansMuller/events{/privacy}","received_events_url":"https://api.github.com/users/HansMuller/received_events","type":"User","site_admin":false},"repo":{"id":45849791,"name":"flutter","full_name":"HansMuller/flutter","owner":{"login":"HansMuller","id":1377460,"avatar_url":"https://avatars.githubusercontent.com/u/1377460?v=3","gravatar_id":"","url":"https://api.github.com/users/HansMuller","html_url":"https://github.com/HansMuller","followers_url":"https://api.github.com/users/HansMuller/followers","following_url":"https://api.github.com/users/HansMuller/following{/other_user}","gists_url":"https://api.github.com/users/HansMuller/gists{/gist_id}","starred_url":"https://api.github.com/users/HansMuller/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HansMuller/subscriptions","organizations_url":"https://api.github.com/users/HansMuller/orgs","repos_url":"https://api.github.com/users/HansMuller/repos","events_url":"https://api.github.com/users/HansMuller/events{/privacy}","received_events_url":"https://api.github.com/users/HansMuller/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/HansMuller/flutter","description":"The Flutter framework","fork":true,"url":"https://api.github.com/repos/HansMuller/flutter","forks_url":"https://api.github.com/repos/HansMuller/flutter/forks","keys_url":"https://api.github.com/repos/HansMuller/flutter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/HansMuller/flutter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/HansMuller/flutter/teams","hooks_url":"https://api.github.com/repos/HansMuller/flutter/hooks","issue_events_url":"https://api.github.com/repos/HansMuller/flutter/issues/events{/number}","events_url":"https://api.github.com/repos/HansMuller/flutter/events","assignees_url":"https://api.github.com/repos/HansMuller/flutter/assignees{/user}","branches_url":"https://api.github.com/repos/HansMuller/flutter/branches{/branch}","tags_url":"https://api.github.com/repos/HansMuller/flutter/tags","blobs_url":"https://api.github.com/repos/HansMuller/flutter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/HansMuller/flutter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/HansMuller/flutter/git/refs{/sha}","trees_url":"https://api.github.com/repos/HansMuller/flutter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/HansMuller/flutter/statuses/{sha}","languages_url":"https://api.github.com/repos/HansMuller/flutter/languages","stargazers_url":"https://api.github.com/repos/HansMuller/flutter/stargazers","contributors_url":"https://api.github.com/repos/HansMuller/flutter/contributors","subscribers_url":"https://api.github.com/repos/HansMuller/flutter/subscribers","subscription_url":"https://api.github.com/repos/HansMuller/flutter/subscription","commits_url":"https://api.github.com/repos/HansMuller/flutter/commits{/sha}","git_commits_url":"https://api.github.com/repos/HansMuller/flutter/git/commits{/sha}","comments_url":"https://api.github.com/repos/HansMuller/flutter/comments{/number}","issue_comment_url":"https://api.github.com/repos/HansMuller/flutter/issues/comments{/number}","contents_url":"https://api.github.com/repos/HansMuller/flutter/contents/{+path}","compare_url":"https://api.github.com/repos/HansMuller/flutter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/HansMuller/flutter/merges","archive_url":"https://api.github.com/repos/HansMuller/flutter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/HansMuller/flutter/downloads","issues_url":"https://api.github.com/repos/HansMuller/flutter/issues{/number}","pulls_url":"https://api.github.com/repos/HansMuller/flutter/pulls{/number}","milestones_url":"https://api.github.com/repos/HansMuller/flutter/milestones{/number}","notifications_url":"https://api.github.com/repos/HansMuller/flutter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/HansMuller/flutter/labels{/name}","releases_url":"https://api.github.com/repos/HansMuller/flutter/releases{/id}","deployments_url":"https://api.github.com/repos/HansMuller/flutter/deployments","created_at":"2015-11-09T16:11:46Z","updated_at":"2015-11-09T16:11:50Z","pushed_at":"2017-01-07T00:03:21Z","git_url":"git://github.com/HansMuller/flutter.git","ssh_url":"git@github.com:HansMuller/flutter.git","clone_url":"https://github.com/HansMuller/flutter.git","svn_url":"https://github.com/HansMuller/flutter","homepage":"http://flutter.io","size":21472,"stargazers_count":0,"watchers_count":0,"language":"Dart","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"flutter:master","ref":"master","sha":"0c42c9b1b24a0a2087a633874ba7e34e9614f8b3","user":{"login":"flutter","id":14101776,"avatar_url":"https://avatars.githubusercontent.com/u/14101776?v=3","gravatar_id":"","url":"https://api.github.com/users/flutter","html_url":"https://github.com/flutter","followers_url":"https://api.github.com/users/flutter/followers","following_url":"https://api.github.com/users/flutter/following{/other_user}","gists_url":"https://api.github.com/users/flutter/gists{/gist_id}","starred_url":"https://api.github.com/users/flutter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flutter/subscriptions","organizations_url":"https://api.github.com/users/flutter/orgs","repos_url":"https://api.github.com/users/flutter/repos","events_url":"https://api.github.com/users/flutter/events{/privacy}","received_events_url":"https://api.github.com/users/flutter/received_events","type":"Organization","site_admin":false},"repo":{"id":31792824,"name":"flutter","full_name":"flutter/flutter","owner":{"login":"flutter","id":14101776,"avatar_url":"https://avatars.githubusercontent.com/u/14101776?v=3","gravatar_id":"","url":"https://api.github.com/users/flutter","html_url":"https://github.com/flutter","followers_url":"https://api.github.com/users/flutter/followers","following_url":"https://api.github.com/users/flutter/following{/other_user}","gists_url":"https://api.github.com/users/flutter/gists{/gist_id}","starred_url":"https://api.github.com/users/flutter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flutter/subscriptions","organizations_url":"https://api.github.com/users/flutter/orgs","repos_url":"https://api.github.com/users/flutter/repos","events_url":"https://api.github.com/users/flutter/events{/privacy}","received_events_url":"https://api.github.com/users/flutter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/flutter/flutter","description":"Framework for building high-performance, high-fidelity iOS and Android apps.","fork":false,"url":"https://api.github.com/repos/flutter/flutter","forks_url":"https://api.github.com/repos/flutter/flutter/forks","keys_url":"https://api.github.com/repos/flutter/flutter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/flutter/flutter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/flutter/flutter/teams","hooks_url":"https://api.github.com/repos/flutter/flutter/hooks","issue_events_url":"https://api.github.com/repos/flutter/flutter/issues/events{/number}","events_url":"https://api.github.com/repos/flutter/flutter/events","assignees_url":"https://api.github.com/repos/flutter/flutter/assignees{/user}","branches_url":"https://api.github.com/repos/flutter/flutter/branches{/branch}","tags_url":"https://api.github.com/repos/flutter/flutter/tags","blobs_url":"https://api.github.com/repos/flutter/flutter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/flutter/flutter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/flutter/flutter/git/refs{/sha}","trees_url":"https://api.github.com/repos/flutter/flutter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/flutter/flutter/statuses/{sha}","languages_url":"https://api.github.com/repos/flutter/flutter/languages","stargazers_url":"https://api.github.com/repos/flutter/flutter/stargazers","contributors_url":"https://api.github.com/repos/flutter/flutter/contributors","subscribers_url":"https://api.github.com/repos/flutter/flutter/subscribers","subscription_url":"https://api.github.com/repos/flutter/flutter/subscription","commits_url":"https://api.github.com/repos/flutter/flutter/commits{/sha}","git_commits_url":"https://api.github.com/repos/flutter/flutter/git/commits{/sha}","comments_url":"https://api.github.com/repos/flutter/flutter/comments{/number}","issue_comment_url":"https://api.github.com/repos/flutter/flutter/issues/comments{/number}","contents_url":"https://api.github.com/repos/flutter/flutter/contents/{+path}","compare_url":"https://api.github.com/repos/flutter/flutter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/flutter/flutter/merges","archive_url":"https://api.github.com/repos/flutter/flutter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/flutter/flutter/downloads","issues_url":"https://api.github.com/repos/flutter/flutter/issues{/number}","pulls_url":"https://api.github.com/repos/flutter/flutter/pulls{/number}","milestones_url":"https://api.github.com/repos/flutter/flutter/milestones{/number}","notifications_url":"https://api.github.com/repos/flutter/flutter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/flutter/flutter/labels{/name}","releases_url":"https://api.github.com/repos/flutter/flutter/releases{/id}","deployments_url":"https://api.github.com/repos/flutter/flutter/deployments","created_at":"2015-03-06T22:54:58Z","updated_at":"2017-01-09T13:49:06Z","pushed_at":"2017-01-09T19:46:13Z","git_url":"git://github.com/flutter/flutter.git","ssh_url":"git@github.com:flutter/flutter.git","clone_url":"https://github.com/flutter/flutter.git","svn_url":"https://github.com/flutter/flutter","homepage":"https://flutter.io","size":21307,"stargazers_count":3743,"watchers_count":3743,"language":"Dart","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":405,"mirror_url":null,"open_issues_count":1514,"forks":405,"open_issues":1514,"watchers":3743,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/flutter/flutter/pulls/7387"},"html":{"href":"https://github.com/flutter/flutter/pull/7387"},"issue":{"href":"https://api.github.com/repos/flutter/flutter/issues/7387"},"comments":{"href":"https://api.github.com/repos/flutter/flutter/issues/7387/comments"},"review_comments":{"href":"https://api.github.com/repos/flutter/flutter/pulls/7387/comments"},"review_comment":{"href":"https://api.github.com/repos/flutter/flutter/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/flutter/flutter/pulls/7387/commits"},"statuses":{"href":"https://api.github.com/repos/flutter/flutter/statuses/e09a328b7bfc996995030f5aba439d8107eeeef6"}}}}
{"actor":{"display_login":"HansMuller"}}