Saltar al contenido principal

Deprecar findChildIndexCallback en favor de findItemIndexCallback en los constructores separados de ListView y SliverList

El parámetro findChildIndexCallback en ListView.separated y SliverList.separated ha sido deprecado en favor de findItemIndexCallback.

Resumen

#

El parámetro findChildIndexCallback en los constructores de ListView.separated y SliverList.separated ha sido deprecado en favor de findItemIndexCallback. El nuevo callback devuelve índices de elementos directamente, eliminando la necesidad de realizar cálculos de índice manuales para tener en cuenta los separadores.

Contexto

#

En los constructores ListView.separated y SliverList.separated, el parámetro findChildIndexCallback se utilizaba para localizar widgets por su clave (key). Sin embargo, este callback devolvía índices de hijos, que incluyen tanto elementos como separadores en el árbol de widgets interno. Esto significaba que los desarrolladores tenían que multiplicar los índices de los elementos por 2 para obtener el índice de hijo correcto, lo que generaba confusión y código propenso a errores.

El nuevo parámetro findItemIndexCallback simplifica esto al trabajar directamente con índices de elementos, que no incluyen separadores. Esto hace que la API sea más intuitiva y reduce la probabilidad de errores en el cálculo de índices.

Si utilizas el parámetro deprecado findChildIndexCallback, verás una advertencia de deprecación (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.

Además, si intentas proporcionar ambos parámetros, te encontrarás con un error de aserción (assertion error):

Cannot provide both findItemIndexCallback and findChildIndexCallback.
Use findItemIndexCallback as findChildIndexCallback is deprecated.

Guía de migración

#

Para migrar de findChildIndexCallback a findItemIndexCallback, reemplaza el nombre del parámetro y elimina cualquier multiplicación de índice que se haya utilizado para tener en cuenta los separadores.

Código antes de la migración:

dart
ListView.separated(
  itemCount: items.length,
  findChildIndexCallback: (Key key) {
    final ValueKey<String> valueKey = key as ValueKey<String>;
    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<String>(items[index]),
      title: Text(items[index]),
    );
  },
  separatorBuilder: (BuildContext context, int index) => const Divider(),
)

Código después de la migración:

dart
ListView.separated(
  itemCount: items.length,
  findItemIndexCallback: (Key key) {
    final ValueKey<String> valueKey = key as ValueKey<String>;
    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<String>(items[index]),
      title: Text(items[index]),
    );
  },
  separatorBuilder: (BuildContext context, int index) => const Divider(),
)

La misma migración se aplica a SliverList.separated:

Código antes de la migración:

dart
SliverList.separated(
  itemCount: items.length,
  findChildIndexCallback: (Key key) {
    final ValueKey<String> valueKey = key as ValueKey<String>;
    final int itemIndex = items.indexOf(valueKey.value);
    return itemIndex == -1 ? null : itemIndex * 2;
  },
  itemBuilder: (BuildContext context, int index) {
    return Container(
      key: ValueKey<String>(items[index]),
      child: Text(items[index]),
    );
  },
  separatorBuilder: (BuildContext context, int index) => const Divider(),
)

Código después de la migración:

dart
SliverList.separated(
  itemCount: items.length,
  findItemIndexCallback: (Key key) {
    final ValueKey<String> valueKey = key as ValueKey<String>;
    final int itemIndex = items.indexOf(valueKey.value);
    return itemIndex == -1 ? null : itemIndex;
  },
  itemBuilder: (BuildContext context, int index) {
    return Container(
      key: ValueKey<String>(items[index]),
      child: Text(items[index]),
    );
  },
  separatorBuilder: (BuildContext context, int index) => const Divider(),
)

Timeline

#

Llegó en la versión: 3.38.0-1.0.pre
En la versión estable: 3.41

Referencias

#

Documentación de la API:

PRs relevantes: