Related
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
),
)
])
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
I tried to build a list by taking the data I pulled from the database. But I do not see anything in any way, I get a white screen. I think the data I pulled is overlapping and preventing building lists but I couldn't find where the error is. What I'm trying to do is divide the Card by Row with 2 and write the data I pulled from the database on the left side of the Card. Write other data on the right.
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _db.getEventsByOrder(widget.index),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(child: Text("Loading.....")),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 16.0),
child: Card(
elevation: 25,
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Row(
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Text(
'${snapshot.data[index].title}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 28, fontFamily: 'Arvo'),
)),
Text(
"${snapshot.data[index].date} - ${snapshot.data[index].startTime == "null" ? " Tüm gün" : "${snapshot.data[index].startTime} - ${snapshot.data[index].finishTime}"}",
style: new TextStyle(
fontSize: 15, fontFamily: 'Arvo'),
),
Expanded(
child: Text(snapshot.data[index].desc,
maxLines: 2,
overflow: TextOverflow.ellipsis),
),
]),
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
child: DropDown(Event(
id: snapshot.data[index].id,
title: snapshot.data[index].title,
date: snapshot.data[index].date,
startTime:
snapshot.data[index].startTime,
finishTime:
snapshot.data[index].finishTime,
desc: snapshot.data[index].desc,
isActive:
snapshot.data[index].isActive,
choice:
snapshot.data[index].choice))),
Container(
padding: EdgeInsets.only(top: 8.0),
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.blue),
child: Text(
"${DateTime.parse(snapshot.data[index].date).difference(DateTime.now()).inDays}\nKalan Gün",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25),
),
),
],
),
],
),
),
),
);
});
}
}),
);
}
You need to adjust the dimensions only.
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _db.getEventsByOrder(widget.index),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(child: Text("Loading.....")),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 16.0),
child: Card(
elevation: 25,
child: Container(
height: MediaQuery.of(context).size.height/4,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 2 - 16,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'${snapshot.data[index].title}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 28),
),
Text(
"${snapshot.data[index].date} - ${snapshot.data[index].startTime == "null" ? " Tüm gün" : "${snapshot.data[index].startTime} - ${snapshot.data[index].finishTime}"}",
style: TextStyle(fontSize: 15),
),
Text(
snapshot.data[index].desc,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
Container(
width: MediaQuery.of(context).size.width / 2 - 32,
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 4 - 8,
child: DropDown(Event(
id: snapshot.data[index].id,
title: snapshot.data[index].title,
date: snapshot.data[index].date,
startTime: snapshot.data[index].startTime,
finishTime: snapshot.data[index].finishTime,
desc: snapshot.data[index].desc,
isActive: snapshot.data[index].isActive,
choice: snapshot.data[index].choice)),
),
],
),
),
),
);
});
}
}),
);
}
If there was even an overlapping problem, should be an error. Provide the debug info and try to move DropDown out of container to column
You could also close ROW in a CONTAINER
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());
}
},
),
I'm kinda stuck with what I'm trying to do. I'm trying to merge my two Stream Builder to show the output as one in a card. In my first StreamBuilder thats where I'm getting some infos of the user like the info that he posted, what they need like that. And in my 2nd StreamBuilder thats where I get his/her name, contacts like that. Is it possible to merge it as one? so I'll get the data as one also.
This is how I use my StreamBuilders.
1st stream:
StreamBuilder<QuerySnapshot>(
stream: db.collection('HELP REQUEST').where('Type_OfDisaster', isEqualTo: '[Drought]').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList()
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator()
)
);
}
}
);
2nd Stream:
StreamBuilder<QuerySnapshot>(
stream: db.collection('USERS').where('User_ID', isEqualTo: widget.Uid).snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList()
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator()
)
);
}
}
);
Here is where I output the data I get in the stream builder:
Container buildItem(DocumentSnapshot doc) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
return Container(
child: Card(
elevation: 5,
child: Padding(
padding: const EdgeInsets.only(top: 20, left: 20, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(
radius: 30,
backgroundColor: Colors.black,
),
SizedBox(
width: 10,
),
Text('Name: '),
Text(
'${doc.data['Name_ofUser']}',
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w500),
)
],
),
],
),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 20,
),
Row(
children: <Widget>[
Text('Date:'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${doc.data['Help_DatePosted']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w500),
),
),
],
),
Row(
children: <Widget>[
Text('Location:'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${doc.data['Help_Location']}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w500),
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text('Description:'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${doc.data['Help_Description']}',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w500),
),
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
height: _height * 0.05,
width: _width * 0.20,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20.0))),
color: Color(0xFF121A21),
onPressed: () {
_viewingRequest(doc.data);
},
child: Text(
'View',
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w800),
),
),
),
)
],
),
],
),
),
),
);
}
Is it possible to do it? Please help me.
You can listen to the snapshots without using a StreamBuilder directly, like this:
List<HelpRequestsPlusUsers> helpRequestsPlusUsers = [];
List<User> allUsers = [];
List<HelpRequest> helpRequests = [];
#override
void initState() {
db.collection('USERS').where('User_ID', isEqualTo: widget.Uid).snapshots().listen((snapshot){
allusers = snapshot.data.documents;
mergeUsersWithHelpRequests();
});
db.collection('HELP REQUEST').where('Type_OfDisaster', isEqualTo: '[Drought]').snapshots().listen((snapshot){
helpRequests = snapshot.data.documents;
mergeUsersWithHelpRequests();
});
super.initState();
}
void mergeUsersWithHelpRequests(){
// Run the code to merge your allUsers and helpRequests data into a helpRequestsPlusUsers List
}
Widget
Widget _buildHelpRequestsPlusUsersWidget (){
if (helpRequestsPlusUsers.isNotEmpty) {
return ListView.builder(
itemBuilder: (context, index){
return buildItem(helpRequestsPlusUsers[index]);
}
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator()
)
);
}
}