#1
https://medium.com/flutterdevs/pagination-in-flutter-with-firebase-firestore-96d6cc11aef2#2
#3
https://www.udemy.com/course/flutter-ios-android-fernando-herrera/learn/lecture/14478706#overviewMi resultado
Esta es mi adaptación aplicada al video anterior + el video 110 StreamBuilder (De la sección 7 Aplicación de películas, del curso de Udemy, flutter-ios-android-fernando-herrera) (ese video es privado) + el tutorial de flutterdevs.
Paginar desde Firebase functions https://fireship.io/lessons/firestore-pagination-guide
const admin = require('firebase-admin');
const pageThree = ref.orderBy(field).limit(10).offset(20);
List view
class DatabasePage extends StatefulWidget {
static final String routeName = 'pagename';
@override
_DatabasePageState createState() => _DatabasePageState();
}
class _DatabasePageState extends State<DatabasePage> {
ProductsProvider productsProvider = new ProductsProvider();
ScrollController controller = ScrollController();
ProductListBloc productListBloc;
@override
void initState() {
super.initState();
productListBloc = ProductListBloc();
productListBloc.fetchNextProducts();
controller.addListener(_scrollListener);
}
void _scrollListener() {
if (controller.offset >= controller.position.maxScrollExtent &&
!controller.position.outOfRange) {
print("at the end of list");
productListBloc.fetchNextProducts();
}
}
@override
void dispose() {
productListBloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('T I T L E'),
backgroundColor: Color.fromRGBO(92, 171, 115, 50),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
color: Colors.white,
onPressed: () =>
Navigator.pushNamed(context, ProductFormPage.routeName)
.then((value) {
setState(() {});
}),
)
],
),
body: _createList(),
);
}
Widget _createList() {
return StreamBuilder(
stream: productListBloc.productStream,
builder:
(BuildContext context, AsyncSnapshot<List<ProductModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
controller: controller,
itemCount: snapshot.data.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index < snapshot.data.length) {
return _createItem(context, snapshot.data[index]);
} else if (productListBloc.hasMore) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 32.0),
child: Center(child: CircularProgressIndicator()),
);
} else {
return Padding(
padding: EdgeInsets.symmetric(vertical: 32.0),
child: Center(child: Text('Fin de la lista.')),
);
}
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
Widget _createItem(BuildContext context, ProductModel item) {
Widget content = ...
...
...
...
return content;
}
}
BLoC
class ProductListBloc {
List<ProductModel> documentList = [];
ProductsProvider productsProvider;
bool hasMore = true;
StreamController<List<ProductModel>> _streamController;
ProductListBloc() {
_streamController = StreamController<List<ProductModel>>();
productsProvider = new ProductsProvider();
hasMore = true;
}
Stream<List<ProductModel>> get productStream => _streamController.stream;
/*This will automatically fetch the next 10 elements from the list*/
fetchNextProducts() async {
try {
List<ProductModel> newDocumentList = (await productsProvider.retrieve(documentList.length));
documentList.addAll(newDocumentList);
_streamController.sink.add(documentList);
hasMore = newDocumentList.length == 30/*page size from backend*/;
} on SocketException {
_streamController.sink.addError(SocketException("No Internet Connection"));
} catch (e) {
print(e.toString());
_streamController.sink.addError(e);
}
}
void dispose() {
_streamController.close();
}
}
No hay comentarios:
Publicar un comentario