Skip to content
4 changes: 2 additions & 2 deletions docs/firebase-ui-firestore.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final usersQuery = FirebaseFirestore.instance.collection('users').orderBy('name'

FirestoreListView<Map<String, dynamic>>(
query: usersQuery,
itemBuilder: (context, snapshot) {
itemBuilder: (context, snapshot, index) {
Map<String, dynamic> user = snapshot.data();

return Text('User name is ${user['name']}');
Expand Down Expand Up @@ -109,7 +109,7 @@ final usersQuery = FirebaseFirestore.instance.collection('users')

FirestoreListView<User>(
query: usersQuery,
itemBuilder: (context, snapshot) {
itemBuilder: (context, snapshot, index) {
// Data is now typed!
User user = snapshot.data();

Expand Down
2 changes: 1 addition & 1 deletion packages/firebase_ui_firestore/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class FirebaseUIFirestoreExample extends StatelessWidget {
body: FirestoreListView<User>(
query: collection,
padding: const EdgeInsets.all(8.0),
itemBuilder: (context, snapshot) {
itemBuilder: (context, snapshot, index) {
final user = snapshot.data();
return Column(
children: [
Expand Down
17 changes: 10 additions & 7 deletions packages/firebase_ui_firestore/lib/src/query_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,11 @@ class _Sentinel {
}

/// A type representing the function passed to [FirestoreListView] for its `itemBuilder`.
typedef FirestoreItemBuilder<Document> =
Widget Function(BuildContext context, QueryDocumentSnapshot<Document> doc);
typedef FirestoreItemBuilder<Document> = Widget Function(
BuildContext context,
QueryDocumentSnapshot<Document> doc,
int index,
);

/// A type representing the function passed to [FirestoreListView] for its `loadingBuilder`.
typedef FirestoreLoadingBuilder = Widget Function(BuildContext context);
Expand Down Expand Up @@ -414,7 +417,7 @@ typedef FirestoreEmptyBuilder = Widget Function(BuildContext context);
/// ```dart
/// FirestoreListView<Movie>(
/// query: moviesCollection.orderBy('title'),
/// itemBuilder: (context, snapshot) {
/// itemBuilder: (context, snapshot, index) {
/// Movie movie = snapshot.data();
/// return Text(movie.title);
/// },
Expand Down Expand Up @@ -499,7 +502,7 @@ class FirestoreListView<Document> extends FirestoreQueryBuilder<Document> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
itemBuilder(context, doc),
itemBuilder(context, doc, index),
if (isLastItem && snapshot.hasMore)
fetchingIndicatorBuilder?.call(context) ??
const Padding(
Expand All @@ -516,7 +519,7 @@ class FirestoreListView<Document> extends FirestoreQueryBuilder<Document> {
],
),
)
: itemBuilder(context, doc);
: itemBuilder(context, doc, index);
},
scrollDirection: scrollDirection,
reverse: reverse,
Expand Down Expand Up @@ -611,7 +614,7 @@ class FirestoreListView<Document> extends FirestoreQueryBuilder<Document> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
itemBuilder(context, doc),
itemBuilder(context, doc, index),
if (isLastItem && snapshot.hasMore)
fetchingIndicatorBuilder?.call(context) ??
const Padding(
Expand All @@ -628,7 +631,7 @@ class FirestoreListView<Document> extends FirestoreQueryBuilder<Document> {
],
),
)
: itemBuilder(context, doc);
: itemBuilder(context, doc, index);
},
separatorBuilder: separatorBuilder,
scrollDirection: scrollDirection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ void main() {
body: FirestoreListView<Map>(
query: collection.orderBy('value'),
loadingBuilder: (context) => const Text('loading...'),
itemBuilder: (context, snapshot) => throw UnimplementedError(),
itemBuilder: (context, snapshot, index) =>
throw UnimplementedError(),
),
),
),
Expand All @@ -77,12 +78,14 @@ void main() {
) async {
final collection = db.collection('flutter-tests/list-view-builder/works');

await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: FirestoreListView<Map>(
query: collection.orderBy('value'),
itemBuilder: (context, snapshot) => throw UnimplementedError(),
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: FirestoreListView<Map>(
query: collection.orderBy('value'),
itemBuilder: (context, snapshot, index) =>
throw UnimplementedError(),
),
),
),
),
Expand All @@ -102,7 +105,8 @@ void main() {
body: FirestoreListView<Map>(
query: collection,
cacheExtent: 0,
itemBuilder: (context, snapshot) => throw UnimplementedError(),
itemBuilder: (context, snapshot, index) =>
throw UnimplementedError(),
),
),
),
Expand Down Expand Up @@ -130,31 +134,32 @@ void main() {
await tester.pumpWidget(
MaterialApp(
home: Material(
child: Builder(
builder: (context) {
final mq = MediaQuery.of(context);
final h = mq.size.height;
size = h / 5;

return FirestoreListView<Map>(
physics: const ClampingScrollPhysics(),
query: ref.orderBy('value'),
cacheExtent: 0,
pageSize: 5,
itemExtent: size,
itemBuilder: (context, snapshot) {
final v = snapshot.data()['value'] as int;

return Container(
alignment: Alignment.center,
color: Colors.black.withAlpha(v % 2 == 0 ? 50 : 100),
key: ValueKey(v.toString()),
child: Text(v.toString(), textAlign: TextAlign.center),
);
},
);
},
),
child: Builder(builder: (context) {
final mq = MediaQuery.of(context);
final h = mq.size.height;
size = h / 5;

return FirestoreListView<Map>(
physics: const ClampingScrollPhysics(),
query: ref.orderBy('value'),
cacheExtent: 0,
pageSize: 5,
itemExtent: size,
itemBuilder: (context, snapshot, index) {
final v = snapshot.data()['value'] as int;

return Container(
alignment: Alignment.center,
color: Colors.black.withAlpha(v % 2 == 0 ? 50 : 100),
key: ValueKey(v.toString()),
child: Text(
v.toString(),
textAlign: TextAlign.center,
),
);
},
);
}),
),
),
);
Expand Down Expand Up @@ -201,7 +206,11 @@ void main() {
}

class ListViewBuilderSpy<T> extends Mock {
Widget call(BuildContext? context, T? snapshot) {
Widget call(
BuildContext? context,
T? snapshot,
int? index,
) {
return super.noSuchMethod(
Invocation.method(#call, [context, snapshot]),
returnValueForMissingStub: Container(),
Expand Down
Loading