diff --git a/src/content/release/breaking-changes/index.md b/src/content/release/breaking-changes/index.md index ef6a3744604..706f8aacaa5 100644 --- a/src/content/release/breaking-changes/index.md +++ b/src/content/release/breaking-changes/index.md @@ -41,12 +41,14 @@ They're sorted by release and listed in alphabetical order: * [`$FLUTTER_ROOT/version` replaced by `$FLUTTER_ROOT/bin/cache/flutter.version.json`][] * [Stop generating `AssetManifest.json`][] * [Deprecate `TextField.canRequestFocus`][] +* [Deprecate `findChildIndexCallback` in favor of `findItemIndexCallback` in `ListView` and `SliverList` separated constructors][] [`FontWeight` also controls the weight attribute of variable fonts]: /release/breaking-changes/font-weight-variation [UISceneDelegate adoption]: /release/breaking-changes/uiscenedelegate [Stop generating `AssetManifest.json`]: /release/breaking-changes/asset-manifest-dot-json [`$FLUTTER_ROOT/version` replaced by `$FLUTTER_ROOT/bin/cache/flutter.version.json`]: /release/breaking-changes/flutter-root-version-file [Deprecate `TextField.canRequestFocus`]: /release/breaking-changes/can-request-focus +[Deprecate `findChildIndexCallback` in favor of `findItemIndexCallback` in `ListView` and `SliverList` separated constructors]: /release/breaking-changes/separated-builder-find-child-index-callback ### Released in Flutter 3.38 diff --git a/src/content/release/breaking-changes/separated-builder-find-child-index-callback.md b/src/content/release/breaking-changes/separated-builder-find-child-index-callback.md new file mode 100644 index 00000000000..a67c0fb21dd --- /dev/null +++ b/src/content/release/breaking-changes/separated-builder-find-child-index-callback.md @@ -0,0 +1,158 @@ +--- +title: Deprecate `findChildIndexCallback` in favor of `findItemIndexCallback` in `ListView` and `SliverList` separated constructors +description: >- + The findChildIndexCallback parameter in ListView.separated and + SliverList.separated have been deprecated in favor of findItemIndexCallback. +--- + +## Summary + +The `findChildIndexCallback` parameter in `ListView.separated` and +`SliverList.separated` constructors have been deprecated in favor of +`findItemIndexCallback`. The new callback returns item indices directly, +eliminating the need for manual index calculations to account for separators. + +## Background + +In `ListView.separated` and `SliverList.separated` constructors, +the `findChildIndexCallback` was used to locate widgets by their key. +However, this callback returned child indices, which include both items +and separators in the internal widget tree. This meant that developers had to +multiply item indices by 2 to get the correct child index, creating +confusion and error-prone code. + +The new `findItemIndexCallback` parameter simplifies this by working +directly with item indices, which do not include separators. +This makes the API more intuitive and reduces the likelihood of +index calculation errors. + +If you use the deprecated `findChildIndexCallback` parameter, +you will see a deprecation warning: + +``` +'findChildIndexCallback' is deprecated and shouldn't be used. +Use findItemIndexCallback instead. +findChildIndexCallback returns child indices (which include separators), +while findItemIndexCallback returns item indices (which do not). +If you were multiplying results by 2 to account for separators, +you can remove that workaround when migrating to findItemIndexCallback. +This feature was deprecated after v3.37.0-1.0.pre. +``` + +Additionally, if you try to provide both parameters, you will encounter +an assertion error: + +``` +Cannot provide both findItemIndexCallback and findChildIndexCallback. +Use findItemIndexCallback as findChildIndexCallback is deprecated. +``` + +## Migration guide + +To migrate from `findChildIndexCallback` to `findItemIndexCallback`, +replace the parameter name and remove any index multiplications +that were used to account for separators. + +Code before migration: + +```dart +ListView.separated( + itemCount: items.length, + findChildIndexCallback: (Key key) { + final ValueKey valueKey = key as ValueKey; + final int itemIndex = items.indexOf(valueKey.value); + // Multiply by 2 to account for separators + return itemIndex == -1 ? null : itemIndex * 2; + }, + itemBuilder: (BuildContext context, int index) { + return ListTile( + key: ValueKey(items[index]), + title: Text(items[index]), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Divider(), +) +``` + +Code after migration: + +```dart +ListView.separated( + itemCount: items.length, + findItemIndexCallback: (Key key) { + final ValueKey valueKey = key as ValueKey; + final int itemIndex = items.indexOf(valueKey.value); + // Return item index directly - no need to multiply by 2 + return itemIndex == -1 ? null : itemIndex; + }, + itemBuilder: (BuildContext context, int index) { + return ListTile( + key: ValueKey(items[index]), + title: Text(items[index]), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Divider(), +) +``` + +The same migration applies to `SliverList.separated`: + +Code before migration: + +```dart +SliverList.separated( + itemCount: items.length, + findChildIndexCallback: (Key key) { + final ValueKey valueKey = key as ValueKey; + final int itemIndex = items.indexOf(valueKey.value); + return itemIndex == -1 ? null : itemIndex * 2; + }, + itemBuilder: (BuildContext context, int index) { + return Container( + key: ValueKey(items[index]), + child: Text(items[index]), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Divider(), +) +``` + +Code after migration: + +```dart +SliverList.separated( + itemCount: items.length, + findItemIndexCallback: (Key key) { + final ValueKey valueKey = key as ValueKey; + final int itemIndex = items.indexOf(valueKey.value); + return itemIndex == -1 ? null : itemIndex; + }, + itemBuilder: (BuildContext context, int index) { + return Container( + key: ValueKey(items[index]), + child: Text(items[index]), + ); + }, + separatorBuilder: (BuildContext context, int index) => const Divider(), +) +``` + +## Timeline + +Landed in version: 3.38.0-1.0.pre
+In stable release: Not yet + +## References + +API documentation: + +* [`ListView.separated`][] +* [`SliverList.separated`][] + +Relevant PRs: + +* [Deprecate findChildIndexCallback for separated constructors][] + +[`ListView.separated`]: {{site.api}}/flutter/widgets/ListView/ListView.separated.html +[`SliverList.separated`]: {{site.api}}/flutter/widgets/SliverList/SliverList.separated.html +[Deprecate findChildIndexCallback for separated constructors]: {{site.repo.flutter}}/pull/174491