Implement pagination in Flutter with a bloc pattern - flutter

Using the NotificationListener, I am trying to integrate pagination with the ListView.Builder, but I don't get the expected result. While the list is working, it scrolls very slowly.
The code I wrote is below
NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
if (_controller.position.maxScrollExtent ==
_controller.offset) {
if (state is LoghistorySuccess) {
if (logsData.length == _index) {
if (pagecount > page) {
setState(() {
page = page + 1;
print(page);
BlocProvider.of<LogHistoryBloc>(
context)
.add(LogHistoryFetchEvent(
page: page));
});
}
}
}
}
if (scrollNotification
is ScrollStartNotification) {
_onStartScroll(scrollNotification.metrics);
} else if (scrollNotification
is ScrollUpdateNotification) {
_onUpdateScroll(scrollNotification.metrics);
} else if (scrollNotification
is ScrollEndNotification) {
_onEndScroll(scrollNotification.metrics);
}
return true;
},
child: logsData.isNotEmpty
? ListView.builder(
controller: _controller,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: logsData.length,
//state.logHistoryModel.results?.logs?.length ?? 0,
itemBuilder: (context, index) {
return Padding(
padding:
const EdgeInsets.only(top: 12.0),
child: DottedBorder(
borderType: BorderType.RRect,
strokeWidth: 1,
dashPattern: [2.5, 2.5],
color:
HexColor(Constants.primary),
radius: Radius.circular(10),
child: Padding(
padding: const EdgeInsets.only(
top: 15.0,
left: 15,
right: 15,
bottom: 8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Container(
width: MediaQuery.of(
context)
.size
.width /
2,
child: Text(
"${logsData[index].date}",
style: TextStyle(
overflow:
TextOverflow
.ellipsis,
fontWeight:
FontWeight
.w500,
fontSize: 16,
color: HexColor(
Constants
.primary),
)),
),
// Text(
// "${state.logHistoryEntity.logs?[index]["entry_date"]}",
// style: TextStyle(
// color:
// Color(0xff555B5F)),
// ),
],
),
Container(
margin: EdgeInsets.only(
top: 15,
),
child: ListView.builder(
shrinkWrap: true,
physics:
NeverScrollableScrollPhysics(),
itemCount:
logsData[index]
.log
?.length ??
0,
//state.logHistoryModel.results?.logs?[index].log?.length ?? 0,
itemBuilder:
(context, _index) {
var _data =
logsData[index]
.log?[_index];
return Padding(
padding:
const EdgeInsets
.only(
bottom:
8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
InkWell(
onTap: () {
summaryPopUp(
context,
_data!);
},
child: Text(
"• ${_data?.startTime} to ${_data?.endTime}",
style: TextStyle(
color: Color(
0xff555B5F)),
),
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
"${_data?.logtype}",
style: TextStyle(
color:
Color(0xffED5B2E)),
),
SizedBox(
width: 20,
),
_data?.createdDate ==
formatted
? Row(
children: [
InkWell(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => EditLogsScreen(log: _data!),
));
},
child: ImageIcon(
AssetImage("assets/icons/pencil.png"),
color: Color(0xff18A558),
size: 20,
),
),
SizedBox(
width: 8,
),
InkWell(
onTap: () {
showDialog(
context: context,
builder: (context) {
return DeletLogConfPopUp(
logId: _data?.id,
log: logsData[_index].log,
index: _index,
);
},
);
},
child: ImageIcon(
AssetImage("assets/icons/delete_icon.png"),
color: Color(0xffE72323),
size: 18,
),
),
],
)
: Container()
],
)
],
),
);
},
),
)
],
),
)),
);
},
)
: Container(),
// Center(
// child: Column(
// children: [
// Image(
// image: AssetImage(
// "assets/images/no_task.png")),
// Text("You don't have any logs yet")
// ],
// ),
// ),
)
with this code pagination works fine but not scrolling fast.

Related

Flutter Infinite Grid View Pagination

I Have an (infinitepagedgridview) which I constructed using the "infinite_scroll_pagination" Library
everything is running perfectly for me but I'm facing an issue using the pagingcontroller.refresh()
method, which is triggered using a button which changes a variable state which controls a specific parameter that causes different api results in the (infinitepagedgridview), My issue is that whenever I click the button, the pagingcontroller gets refreshed but the first three elements in the gridview which are the first page results come from the last api request before the button got pressed and the rest of the paginated pages work perfectly.
button code:
onTap: () async {
setState(() => FFAppState().homecat = 'Bags');
setState(() => _pagingController?.refresh());
}
listcode and api call:
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: RefreshIndicator(
onRefresh: () async {
setState(() => _pagingController?.refresh());
await waitForOnePage();
},
child: PagedGridView<ApiPagingParams, dynamic>(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 0.0,
crossAxisSpacing: 5.0,
crossAxisCount: 2,
childAspectRatio: 0.59,
),
pagingController: () {
if (_pagingController != null) {
return _pagingController!;
}
_pagingController = PagingController(
firstPageKey: ApiPagingParams(
nextPageNumber: 0,
numItems: 0,
lastResponse: null,
),
);
_pagingController!
.addPageRequestListener((nextPageMarker) {
GetAllProductsCall.call(
offset: nextPageMarker.numItems,
categoryCatName: FFAppState().homecat)
.then((gridViewinfiniteGetAllProductsResponse) {
List pageItems = getJsonField(
gridViewinfiniteGetAllProductsResponse.jsonBody,
r'''$.results''',
).toList() as List;
// print('22' + pageItems.toString());
final newNumItems =
nextPageMarker.numItems + pageItems.length;
_pagingController!.appendPage(
pageItems,
(pageItems.length > 0)
? ApiPagingParams(
nextPageNumber:
nextPageMarker.nextPageNumber + 1,
numItems: newNumItems,
lastResponse:
gridViewinfiniteGetAllProductsResponse,
)
: null,
);
});
#override
#override
void didUpdateWidget(PagedGridView oldWidget) {
_pagingController?.refresh();
}
});
return _pagingController!;
}(),
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
builderDelegate: PagedChildBuilderDelegate<dynamic>(
// Customize what your widget looks like when it's loading the first page.
firstPageProgressIndicatorBuilder: (_) => Center(
child: SizedBox(
width: 50,
height: 50,
child: CircularProgressIndicator(
color: FlutterFlowTheme.of(context).primaryColor,
),
),
),
itemBuilder: (context, _, kokoIndex) {
final kokoItem =
_pagingController!.itemList![kokoIndex];
return InkWell(
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetailsWidget(
id: getJsonField(
kokoItem,
r'''$.id''',
).toString(),
),
),
);
},
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 0),
child: ClipRRect(
borderRadius:
BorderRadius.circular(0),
child: Image.network(
getJsonField(
kokoItem,
r'''$.thumbnail_img1''',
),
width: MediaQuery.of(context)
.size
.width,
height: MediaQuery.of(context)
.size
.height *
0.3,
fit: BoxFit.cover,
),
),
),
],
),
),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: AutoSizeText(
getJsonField(
kokoItem,
r'''$.title''',
).toString(),
textAlign: TextAlign.right,
maxLines: 2,
style: FlutterFlowTheme.of(context)
.bodyText1
.override(
fontFamily: 'Cairo',
fontSize: 13,
useGoogleFonts: GoogleFonts
.asMap()
.containsKey(
FlutterFlowTheme.of(
context)
.bodyText1Family),
),
),
),
ToggleIcon(
onPressed: () async {
setState(() =>
FFAppState().smallsize =
!FFAppState().smallsize);
},
value: FFAppState().smallsize,
onIcon: Icon(
Icons.favorite,
color: Colors.black,
size: 25,
),
offIcon: Icon(
Icons.favorite_border,
color: Colors.black,
size: 25,
),
)
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
functions.priceformat(getJsonField(
kokoItem,
r'''$.price''',
)),
style: FlutterFlowTheme.of(context)
.bodyText1,
),
Icon(
FFIcons.kshekel,
color: Color(0xD8000000),
size: 13,
),
],
),
],
),
),
);
},
),
),
),
),
),
],
),
).animateOnActionTrigger(
animationsMap['columnOnActionTriggerAnimation']!,
hasBeenTriggered: hasColumnTriggered),
),
);
}
I tried loading using future or clearing the paging controller before refreshing neither worked,
any help would be much appreciated :)

List view childs get out of container

I am trying to make a list view only occupy part of the screen, but it keeps growing till the end not respecting the contianer constraints. I tried to use a sizedbox too but it didn' work. List tiles outside the container are shown without any widget inside, but the background is shown anyways
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: pedidos,
builder: (context, AsyncSnapshot<List<Pedido>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.6,
child: ListView.builder(
itemCount: snapshot.data!.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Hero(
tag:
"pedidos_card${snapshot.data![index].idPedido}",
child: ListTile(
tileColor: Colors.white,
leading: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle),
child: Center(
child: Text(
style: Theme.of(context)
.textTheme
.headlineSmall,
"${snapshot.data![index].idPedido}"),
),
),
title: Text(
'Pedido: ${snapshot.data![index].idPedido}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10),
Text(
'Estado: ${snapshot.data![index].estadoPedido.last.tipoEstadoPedido.name}'),
SizedBox(height: 10),
Text(
"Cliente: ${snapshot.data![index].cliente.nombre}")
],
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
trailing: Checkbox(
value: pedidosSeleccion
.contains(snapshot.data![index]),
onChanged: (bool? value) {
// value = checkboxList[index];
// setState(() {});
},
),
onTap: () {
bool isSelected = pedidosSeleccion
.contains(snapshot.data![index]);
if (isSelected) {
pedidosSeleccion
.remove(snapshot.data![index]);
} else {
pedidosSeleccion.add(snapshot.data![index]);
}
setState(() {});
},
),
));
}),
),
ElevatedButton(
onPressed: () {}, child: Text('Ver ultima milla')),
],
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
});
}
}
example
you can use Expanded instead of Sizedbox
eg:-
Column(
children:[
Expanded(flex:9,
child: ListView(
padding: const EdgeInsets.only(top: 10.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
),
),
Expanded(flex:1,
child:
ElevatedButton(
// fill in required params
),
)
])

Issue with callback

I would like to create a generic dialog but I have some issue with the callback... Here is my code :
The dialog :
class ConfirmDialog {
static Future show<T>(BuildContext context, String message,
void Function(T) onConfirm, VoidCallback? onRefuse) {
return showDialog(
context: context,
builder: (context) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.grey[300],
),
child: Container(
padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
width: 400,
height: 200,
child: Card(
child: Column(
children: [
Text(
message,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 30),
),
Container(
margin: EdgeInsets.fromLTRB(0, 20, 0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
child: Container(
height: 70,
padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
child: Image.asset("assets/images/confirm.png"),
),
onTap: () => {
onConfirm,
print("accept"),
Navigator.pop(context),
}),
GestureDetector(
child: Container(
height: 70,
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Image.asset("assets/images/cancel.png"),
),
onTap: () => {
if (onRefuse != null)
{
onRefuse,
}
else
{
Navigator.pop(context),
}
print("refuse")
},
),
],
),
),
],
),
),
),
);
},
);
}
The widget :
Widget listView(List<Product> products) {
return ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
Product product = products[index];
return GestureDetector(
child: Container(
height: 150,
child: Card(
child: Row(
children: [
Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
width: 150,
height: 150,
child: Image.network(product.small),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
softWrap: false,
style: TextStyle(
fontSize: 30,
),
),
Text(
product.getBrand(),
style: TextStyle(
color: Colors.grey,
fontSize: 25,
fontFamily: "Antonio",
),
)
],
),
)
],
),
),
),
onTap: () => {},
onLongPress: () => {
ConfirmDialog.show<Product>(
context,
"Are you sure you want to delete\n${product.name} ?",
deleteSelectedProduct(product),
null,
)
},
);
},
);
}
Everytime I "longpress", I got this error message :
The following _TypeError was thrown while handling a gesture: type
'Null' is not a subtype of type '(Product) => dynamic'
The product I pass as parameter is not null and the dialog don't show up but the method "deleteSelectedProduct" is triggered.
I can't figure out where I got it wrong?
If someone can help, it would be great!
Thank you in advance
The function is being called before it is passed in, so it will return null and pass that value in. You would need to use deleteSelectedProduct instead of deleteSelectedProduct(product)

Flutter: Errors when wrapping Layoutbuilder and Text in Column

I currently have a listview with an alphabet scroller on the side. I'm trying to add a searchbox to the top, but whenever I wrap something in a column, I get errors.
Using the current code, ListView inside Stack is throwing Vertical viewport was given unbounded height.
When I remove the column and Text('TestString'), my code works fine. I have tried adding an Expandable around the ListView.Builder but this also doesn't seem to solve it.
#override
Widget build(BuildContext context) {
height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: Text(widget.title,
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.bold)),
centerTitle: true,
),
body: Column(
children: [
Text('TestString'),
new LayoutBuilder(
builder: (context, constraints) {
return new Stack(children: [
//Causes the current issue
ListView.builder(
itemCount: exampleList.length,
controller: _controller,
itemExtent: _itemsizeheight,
itemBuilder: (context, position) {
return Padding(
padding: const EdgeInsets.only(right: 32.0),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
exampleList[position],
style: TextStyle(fontSize: 20.0),
),
),
));
},
),
Positioned(
right: _marginRight,
top: _offsetContainer,
child: _getSpeechBubble()),
Align(
alignment: Alignment.centerRight,
child: GestureDetector(
onTapDown: (details) {
_onTapDown(details);
},
child: GestureDetector(
onVerticalDragUpdate: _onVerticalDragUpdate,
onVerticalDragStart: _onVerticalDragStart,
onVerticalDragEnd: (details) {
setState(() {
isPressed = false;
});
},
child: Container(
//height: 20.0 * 26,
color: Colors.transparent,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: []..addAll(
new List.generate(_alphabet.length,
(index) => _getAlphabetItem(index)),
),
),
),
),
),
),
]);
},
),
],
),
);
}
_getSpeechBubble() {
return isPressed
? new SpeechBubble(
nipLocation: NipLocation.RIGHT,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 30,
child: Center(
child: Text(
"${_text ?? "${_alphabet.first}"}",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
),
),
],
),
)
: SizedBox.shrink();
}
ValueGetter? callback(int value) {}
_getAlphabetItem(int index) {
return new Expanded(
child: new Container(
width: 40,
height: 20,
alignment: Alignment.center,
child: new Text(
_alphabet[index],
style: (index == posSelected)
? new TextStyle(fontSize: 16, fontWeight: FontWeight.w700)
: new TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
),
),
);
}
You can wrap your LayoutBuilder() with Expanded() like this and it won't show an error.
return Container(
child: Column(
children: [
Text("Header"),
Expanded(
child: ListView.builder(
itemCount:50,
itemBuilder: (BuildContext context, int index) {
return Text("List Item $index");
},
),
),
Text("Footer"),
],
),
);
You can try the code here

Why does my application close when I use a listview with Cards and NetworkImage?

The ListView.builder is being built with some cards that contain NetworkImage, for the moment it creates 25 cards for me, therefore it has to load 25 images, at the moment of making a slide the application remains stopped and at the end it closes, which could be doing wrong? Here is the code, I would appreciate if you could help me. Images are stored in Firebase Storage and weigh less than 300 kb,
It is also worth mentioning that when I scroll through the listview the images are reloaded.
FutureBuilder(
future: urlPublicaciones.cargarUrlPublicaciones(),
builder: (BuildContext context,
AsyncSnapshot<List<UrlPublicacionesModel>> snapshotUrl) {
if (snapshotUrl.hasData) {
urlPosts = snapshotUrl.data;
return FutureBuilder(
future: urlPublicaciones.cargarPublicaciones(urlPosts),
builder: (BuildContext context,
AsyncSnapshot<List<CategoriasResponse>> snapshot) {
if (snapshot.hasData) {
publicaciones = snapshot.data;
if (publicaciones.isNotEmpty) {
return ListView.builder(
itemCount: publicaciones.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
confirmDismiss: (direction) async {
switch (direction) {
case DismissDirection.endToStart:
return await _showConfirmationDialog(
context) ==
true;
case DismissDirection.startToEnd:
return await _showConfirmationDialog(
context) ==
true;
case DismissDirection.horizontal:
case DismissDirection.vertical:
case DismissDirection.up:
case DismissDirection.down:
assert(false);
}
return false;
},
background: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerLeft,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
secondaryBackground: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerRight,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
key: UniqueKey(),
onDismissed: (direction) async {
_showCircularProgressDelete(context);
if (await urlPublicaciones
.eliminarPublicacion(urlPosts[index])) {
setState(() {
publicaciones.removeAt(index);
});
Navigator.pop(context);
}
else {
Navigator.pop(context);
await _showErrorDialog(context);
}
},
child: _tarjeta(
context, publicaciones[index], index));
},
);
} else {
return Center(
child: Text(
'Aún no cuentas con ninguna publicación',
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center));
}
} else {
return Center(child: CircularProgressIndicator());
}
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
Widget _tarjeta(
BuildContext context,
CategoriasResponse publicacion, int index) {
colores = _calculoPuntuacion(publicacion.calificacion.calificacion_total);
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 10),
child: GestureDetector(
onTap: () {
Navigator.pushNamed(context, 'detalle_mipublicacion',
arguments: publicacion);
},
child: Card(
elevation: 10.0,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
child: Column(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 10.0,
),
Container(
padding:
EdgeInsetsDirectional.fromSTEB(5.0, 10.0, 10.0, 0.0),
alignment: AlignmentDirectional.center,
child: _cargarImagen(publicacion)),
Column(
children: <Widget>[
SizedBox(
height: 28.0,
child: Text(
publicacion.nombre,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
textAlign: TextAlign.center,
)),
Text(
'Categoria: ' + publicacion.categoria,
style: TextStyle(
fontWeight: FontWeight.normal, fontSize: 15.0),
textAlign: TextAlign.center,
)
],
),
],
),
Column(
children: <Widget>[
SizedBox(
height: 35.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star, color: colores[0]),
Icon(Icons.star, color: colores[1]),
Icon(Icons.star, color: colores[2]),
Icon(Icons.star, color: colores[3]),
Icon(Icons.star, color: colores[4]),
Text(publicacion.calificacion.calificacion_total
.toString())
],
),
)
],
),
Column(
children: <Widget>[
Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.phone, color: Colors.orangeAccent),
Text(publicacion.telefono.toString(),
overflow: TextOverflow.ellipsis)
],
),
]),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.location_on,
color: Colors.orangeAccent),
Text(publicacion.direccion,
overflow: TextOverflow.ellipsis)
],
),
]),
],
),
],
),
SizedBox(height: 10)
],
),
),
),
);
}
Widget _cargarImagen(CategoriasResponse publicacion) {
final logo = Container(
child: Card(
elevation: 5.0,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: FadeInImage(
placeholder: AssetImage('assets/img/giphy.gif'),
image: NetworkImage(publicacion.fotos.url1),
height: 150.0,
width: 170.0,
fit: BoxFit.fill),
),
),
);
return logo;
}
Try this:
FutureBuilder(
future: urlPublicaciones.cargarUrlPublicaciones(),
builder: (BuildContext context,
AsyncSnapshot<List<UrlPublicacionesModel>> snapshotUrl) {
if (snapshotUrl.hasData) {
urlPosts = snapshotUrl.data;
return FutureBuilder(
future: urlPublicaciones.cargarPublicaciones(urlPosts),
builder: (BuildContext context,
AsyncSnapshot<List<CategoriasResponse>> snapshot) {
if (snapshot.hasData) {
publicaciones = snapshot.data;
if (publicaciones.isNotEmpty) {
return ListView.builder(
itemCount: publicaciones.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
confirmDismiss: (direction) async {
switch (direction) {
case DismissDirection.endToStart:
return await _showConfirmationDialog(
context);
case DismissDirection.startToEnd:
return await _showConfirmationDialog(
context);
}
},
background: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerLeft,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
secondaryBackground: Container(
padding:
EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerRight,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 50.0,
),
),
key: UniqueKey(),
onDismissed: (direction) async {
_showCircularProgressDelete(context);
if (await urlPublicaciones
.eliminarPublicacion(urlPosts[index])) {
setState(() {
publicaciones.removeAt(index);
});
Navigator.pop(context);
}
else {
Navigator.pop(context);
await _showErrorDialog(context);
}
},
child: _tarjeta(
context, publicaciones[index], index));
},
);
} else {
return Center(
child: Text(
'Aún no cuentas con ninguna publicación',
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center));
}
} else {
return Center(child: CircularProgressIndicator());
}
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),