{"action":"created","comment":{"url":"https://api.github.com/repos/flutter/flutter/pulls/comments/207680768","pull_request_review_id":143350993,"id":207680768,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNzY4MDc2OA==","diff_hunk":"@@ -529,35 +553,169 @@ class RenderListWheelViewport\n     size = constraints.biggest;\n   }\n \n+  /// Get the index of a child by looking at its parentData.\n+  int indexOf(RenderBox child) {\n+    assert(child != null);\n+    final ListWheelParentData childParentData = child.parentData;\n+    assert(childParentData.index != null);\n+    return childParentData.index;\n+  }\n+\n+  /// Return the index of the child that should be at the given offset.\n+  int scrollOffsetToIndex(double scrollOffset) => (scrollOffset / itemExtent).floor();\n+\n+  /// Return the scroll offset of the child with the given index.\n+  double indexToScrollOffset(int index) => index * itemExtent;\n+\n+  // Create a child at the given index.\n+  void _createChild(int index, {RenderBox after}) {\n+    invokeLayoutCallback<BoxConstraints>((BoxConstraints constraints) {\n+      assert(constraints == this.constraints);\n+      childManager.createChild(index, after: after);\n+    });\n+  }\n+\n+  void _destroyChild(RenderBox child) {\n+    invokeLayoutCallback<BoxConstraints>((BoxConstraints constraints) {\n+      assert(constraints == this.constraints);\n+      childManager.removeChild(child);\n+    });\n+  }\n+\n+  void _layoutChild(RenderBox child, BoxConstraints constraints, int index) {\n+    child.layout(constraints, parentUsesSize: true);\n+    final ListWheelParentData childParentData = child.parentData;\n+    final double crossPosition = size.width / 2.0 - child.size.width / 2.0;\n+    childParentData.offset = new Offset(crossPosition, indexToScrollOffset(index));\n+  }\n+\n+  /// Layout base on children provided by [childManager].\n+  ///\n+  /// From the current scroll offset, we can calculate the minimum index and\n+  /// maximum index that is visible in the viewport. We can also get the index\n+  /// range of the children that are currently active.\n+  /// We will modify the child list so that children that are not visible\n+  /// will be removed, and those that should visible but not yet created will be\n+  /// instantiate by the childManager.\n   @override\n   void performLayout() {\n-    double currentOffset = 0.0;\n+    final BoxConstraints childConstraints =\n+      constraints.copyWith(\n+        minHeight: _itemExtent,\n+        maxHeight: _itemExtent,\n+        minWidth: 0.0,\n+      );\n+\n+    // The height, in pixel, that children will be visible and might be laid out\n+    // and painted.\n+    double visibleHeight = size.height;\n+    // If [renderChildrenOutsideViewport] is true, we spawn a redundant amount\n+    // of children, those that are in the backside of the cylinder won't be\n+    // painted anyway.\n+    if (renderChildrenOutsideViewport)\n+      visibleHeight *= 2;\n+\n+    final double firstVisibleOffset =\n+        offset.pixels + _itemExtent / 2 - visibleHeight / 2;\n+    final double lastVisibleOffset = firstVisibleOffset + visibleHeight;\n+\n+    // The index range that we want to spawn children. We find indexes that\n+    // are in the interval [firstVisibleOffset, lastVisibleOffset).\n+    int targetFirstIndex = scrollOffsetToIndex(firstVisibleOffset);\n+    int targetLastIndex = scrollOffsetToIndex(lastVisibleOffset);\n+    // Because we exclude lastVisibleOffset, if there's a new child starting at\n+    // that offset, it is removed.\n+    if (targetLastIndex * _itemExtent == lastVisibleOffset)\n+      targetLastIndex--;\n+\n+    // Validate the target range.\n+    while (!childManager.childExistsAt(targetFirstIndex) && targetFirstIndex <= targetLastIndex)\n+      targetFirstIndex++;\n+    while (!childManager.childExistsAt(targetLastIndex) && targetFirstIndex <= targetLastIndex)\n+      targetLastIndex--;\n+\n+    // If it turns out there's no children to layout, we remove old children and\n+    // return.\n+    if (targetFirstIndex > targetLastIndex) {\n+      while (firstChild != null)\n+        _destroyChild(firstChild);\n+      return;\n+    }\n+\n+    // Now there are 2 cases:\n+    //  - The target child list and our current child list have intersection:\n+    //    We shorten and extend our current child list so that the two lists\n+    //    match. Most of the time we are in this case.\n+    //  - The target list and our current child list have no intersection:\n+    //    We first remove all children and then add one child from the target\n+    //    list => this case becomes the other case.\n+\n+    // Case when there is no intersection.","path":"packages/flutter/lib/src/rendering/list_wheel_viewport.dart","position":307,"original_position":307,"commit_id":"26ba2798005de05d57ba13868e7114eba8f0d28c","original_commit_id":"26ba2798005de05d57ba13868e7114eba8f0d28c","user":{"login":"doxuanviet1996","id":9079172,"node_id":"MDQ6VXNlcjkwNzkxNzI=","avatar_url":"https://avatars0.githubusercontent.com/u/9079172?v=4","gravatar_id":"","url":"https://api.github.com/users/doxuanviet1996","html_url":"https://github.com/doxuanviet1996","followers_url":"https://api.github.com/users/doxuanviet1996/followers","following_url":"https://api.github.com/users/doxuanviet1996/following{/other_user}","gists_url":"https://api.github.com/users/doxuanviet1996/gists{/gist_id}","starred_url":"https://api.github.com/users/doxuanviet1996/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/doxuanviet1996/subscriptions","organizations_url":"https://api.github.com/users/doxuanviet1996/orgs","repos_url":"https://api.github.com/users/doxuanviet1996/repos","events_url":"https://api.github.com/users/doxuanviet1996/events{/privacy}","received_events_url":"https://api.github.com/users/doxuanviet1996/received_events","type":"User","site_admin":false},"body":"The no-intersection case happens when the controller jumps to some position that is very far away (for example, when testing). It is true that we will never encounter the second case only by manual scrolling.\r\nCan you be more specific about helper methods?","created_at":"2018-08-03T22:22:49Z","updated_at":"2018-08-03T22:22:49Z","html_url":"https://github.com/flutter/flutter/pull/19789#discussion_r207680768","pull_request_url":"https://api.github.com/repos/flutter/flutter/pulls/19789","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/flutter/flutter/pulls/comments/207680768"},"html":{"href":"https://github.com/flutter/flutter/pull/19789#discussion_r207680768"},"pull_request":{"href":"https://api.github.com/repos/flutter/flutter/pulls/19789"}},"in_reply_to_id":207666998},"pull_request":{"url":"https://api.github.com/repos/flutter/flutter/pulls/19789","id":203989132,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAzOTg5MTMy","html_url":"https://github.com/flutter/flutter/pull/19789","diff_url":"https://github.com/flutter/flutter/pull/19789.diff","patch_url":"https://github.com/flutter/flutter/pull/19789.patch","issue_url":"https://api.github.com/repos/flutter/flutter/issues/19789","number":19789,"state":"open","locked":false,"title":"Support infinite scrolling for CupertinoPicker.","user":{"login":"doxuanviet1996","id":9079172,"node_id":"MDQ6VXNlcjkwNzkxNzI=","avatar_url":"https://avatars0.githubusercontent.com/u/9079172?v=4","gravatar_id":"","url":"https://api.github.com/users/doxuanviet1996","html_url":"https://github.com/doxuanviet1996","followers_url":"https://api.github.com/users/doxuanviet1996/followers","following_url":"https://api.github.com/users/doxuanviet1996/following{/other_user}","gists_url":"https://api.github.com/users/doxuanviet1996/gists{/gist_id}","starred_url":"https://api.github.com/users/doxuanviet1996/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/doxuanviet1996/subscriptions","organizations_url":"https://api.github.com/users/doxuanviet1996/orgs","repos_url":"https://api.github.com/users/doxuanviet1996/repos","events_url":"https://api.github.com/users/doxuanviet1996/events{/privacy}","received_events_url":"https://api.github.com/users/doxuanviet1996/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-07-25T23:18:13Z","updated_at":"2018-08-03T22:22:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f970189ebea13e1afe13792e793344fb238dbc98","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":487496476,"node_id":"MDU6TGFiZWw0ODc0OTY0NzY=","url":"https://api.github.com/repos/flutter/flutter/labels/cla:%20yes","name":"cla: yes","color":"ffffff","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/flutter/flutter/pulls/19789/commits","review_comments_url":"https://api.github.com/repos/flutter/flutter/pulls/19789/comments","review_comment_url":"https://api.github.com/repos/flutter/flutter/pulls/comments{/number}","comments_url":"https://api.github.com/repos/flutter/flutter/issues/19789/comments","statuses_url":"https://api.github.com/repos/flutter/flutter/statuses/26ba2798005de05d57ba13868e7114eba8f0d28c","head":{"label":"doxuanviet1996:infinite_list","ref":"infinite_list","sha":"26ba2798005de05d57ba13868e7114eba8f0d28c","user":{"login":"doxuanviet1996","id":9079172,"node_id":"MDQ6VXNlcjkwNzkxNzI=","avatar_url":"https://avatars0.githubusercontent.com/u/9079172?v=4","gravatar_id":"","url":"https://api.github.com/users/doxuanviet1996","html_url":"https://github.com/doxuanviet1996","followers_url":"https://api.github.com/users/doxuanviet1996/followers","following_url":"https://api.github.com/users/doxuanviet1996/following{/other_user}","gists_url":"https://api.github.com/users/doxuanviet1996/gists{/gist_id}","starred_url":"https://api.github.com/users/doxuanviet1996/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/doxuanviet1996/subscriptions","organizations_url":"https://api.github.com/users/doxuanviet1996/orgs","repos_url":"https://api.github.com/users/doxuanviet1996/repos","events_url":"https://api.github.com/users/doxuanviet1996/events{/privacy}","received_events_url":"https://api.github.com/users/doxuanviet1996/received_events","type":"User","site_admin":false},"repo":{"id":140634727,"node_id":"MDEwOlJlcG9zaXRvcnkxNDA2MzQ3Mjc=","name":"flutter","full_name":"doxuanviet1996/flutter","owner":{"login":"doxuanviet1996","id":9079172,"node_id":"MDQ6VXNlcjkwNzkxNzI=","avatar_url":"https://avatars0.githubusercontent.com/u/9079172?v=4","gravatar_id":"","url":"https://api.github.com/users/doxuanviet1996","html_url":"https://github.com/doxuanviet1996","followers_url":"https://api.github.com/users/doxuanviet1996/followers","following_url":"https://api.github.com/users/doxuanviet1996/following{/other_user}","gists_url":"https://api.github.com/users/doxuanviet1996/gists{/gist_id}","starred_url":"https://api.github.com/users/doxuanviet1996/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/doxuanviet1996/subscriptions","organizations_url":"https://api.github.com/users/doxuanviet1996/orgs","repos_url":"https://api.github.com/users/doxuanviet1996/repos","events_url":"https://api.github.com/users/doxuanviet1996/events{/privacy}","received_events_url":"https://api.github.com/users/doxuanviet1996/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/doxuanviet1996/flutter","description":"Flutter makes it easy and fast to build beautiful mobile apps.","fork":true,"url":"https://api.github.com/repos/doxuanviet1996/flutter","forks_url":"https://api.github.com/repos/doxuanviet1996/flutter/forks","keys_url":"https://api.github.com/repos/doxuanviet1996/flutter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/doxuanviet1996/flutter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/doxuanviet1996/flutter/teams","hooks_url":"https://api.github.com/repos/doxuanviet1996/flutter/hooks","issue_events_url":"https://api.github.com/repos/doxuanviet1996/flutter/issues/events{/number}","events_url":"https://api.github.com/repos/doxuanviet1996/flutter/events","assignees_url":"https://api.github.com/repos/doxuanviet1996/flutter/assignees{/user}","branches_url":"https://api.github.com/repos/doxuanviet1996/flutter/branches{/branch}","tags_url":"https://api.github.com/repos/doxuanviet1996/flutter/tags","blobs_url":"https://api.github.com/repos/doxuanviet1996/flutter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/doxuanviet1996/flutter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/doxuanviet1996/flutter/git/refs{/sha}","trees_url":"https://api.github.com/repos/doxuanviet1996/flutter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/doxuanviet1996/flutter/statuses/{sha}","languages_url":"https://api.github.com/repos/doxuanviet1996/flutter/languages","stargazers_url":"https://api.github.com/repos/doxuanviet1996/flutter/stargazers","contributors_url":"https://api.github.com/repos/doxuanviet1996/flutter/contributors","subscribers_url":"https://api.github.com/repos/doxuanviet1996/flutter/subscribers","subscription_url":"https://api.github.com/repos/doxuanviet1996/flutter/subscription","commits_url":"https://api.github.com/repos/doxuanviet1996/flutter/commits{/sha}","git_commits_url":"https://api.github.com/repos/doxuanviet1996/flutter/git/commits{/sha}","comments_url":"https://api.github.com/repos/doxuanviet1996/flutter/comments{/number}","issue_comment_url":"https://api.github.com/repos/doxuanviet1996/flutter/issues/comments{/number}","contents_url":"https://api.github.com/repos/doxuanviet1996/flutter/contents/{+path}","compare_url":"https://api.github.com/repos/doxuanviet1996/flutter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/doxuanviet1996/flutter/merges","archive_url":"https://api.github.com/repos/doxuanviet1996/flutter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/doxuanviet1996/flutter/downloads","issues_url":"https://api.github.com/repos/doxuanviet1996/flutter/issues{/number}","pulls_url":"https://api.github.com/repos/doxuanviet1996/flutter/pulls{/number}","milestones_url":"https://api.github.com/repos/doxuanviet1996/flutter/milestones{/number}","notifications_url":"https://api.github.com/repos/doxuanviet1996/flutter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/doxuanviet1996/flutter/labels{/name}","releases_url":"https://api.github.com/repos/doxuanviet1996/flutter/releases{/id}","deployments_url":"https://api.github.com/repos/doxuanviet1996/flutter/deployments","created_at":"2018-07-11T22:45:58Z","updated_at":"2018-07-26T23:30:42Z","pushed_at":"2018-08-03T21:51:12Z","git_url":"git://github.com/doxuanviet1996/flutter.git","ssh_url":"git@github.com:doxuanviet1996/flutter.git","clone_url":"https://github.com/doxuanviet1996/flutter.git","svn_url":"https://github.com/doxuanviet1996/flutter","homepage":"https://flutter.io","size":43695,"stargazers_count":0,"watchers_count":0,"language":"Dart","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"flutter:master","ref":"master","sha":"9ffa1c51748229a27dd72a847582de37ff322d17","user":{"login":"flutter","id":14101776,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2","avatar_url":"https://avatars3.githubusercontent.com/u/14101776?v=4","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,"node_id":"MDEwOlJlcG9zaXRvcnkzMTc5MjgyNA==","name":"flutter","full_name":"flutter/flutter","owner":{"login":"flutter","id":14101776,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTAxNzc2","avatar_url":"https://avatars3.githubusercontent.com/u/14101776?v=4","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":"Flutter makes it easy and fast to build beautiful mobile 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":"2018-08-03T21:49:28Z","pushed_at":"2018-08-03T22:22:11Z","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":43403,"stargazers_count":34267,"watchers_count":34267,"language":"Dart","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3165,"mirror_url":null,"archived":false,"open_issues_count":3673,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":3165,"open_issues":3673,"watchers":34267,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/flutter/flutter/pulls/19789"},"html":{"href":"https://github.com/flutter/flutter/pull/19789"},"issue":{"href":"https://api.github.com/repos/flutter/flutter/issues/19789"},"comments":{"href":"https://api.github.com/repos/flutter/flutter/issues/19789/comments"},"review_comments":{"href":"https://api.github.com/repos/flutter/flutter/pulls/19789/comments"},"review_comment":{"href":"https://api.github.com/repos/flutter/flutter/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/flutter/flutter/pulls/19789/commits"},"statuses":{"href":"https://api.github.com/repos/flutter/flutter/statuses/26ba2798005de05d57ba13868e7114eba8f0d28c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"doxuanviet1996"}}