Why can't I scroll page? - flutter

I have a widget ListView but still I can't scroll through the pictures. I tried replacing Column but still it didn't work for me. Is there any other option?
Also, when I wrap StreamBuilder with SingleChildScrollView I get following error:
RenderBox was not laid out: RenderRepaintBoundary#9fda5 relayoutBoundary=up11 NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1702 pos 12: 'hasSize'
Here is my code:
StreamBuilder(
stream: Firestore.instance
.collection('userImage')
// .orderBy('date', descending: true)
.where('name', isEqualTo: name)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
return ListView(
children: [
Row(
children: [
Text('$name'),
IconButton(
icon: Icon(
Icons.open_in_new,
size: 30,
color: Colors.grey,
),
onPressed: logout)
],
),
Row(
children: [
Image.asset(
'assets/like.png',
height: 30,
width: 30,
),
Image.asset(
'assets/donate.png',
height: 30,
width: 30,
),
Icon(
Icons.offline_bolt,
color: Colors.grey,
size: 36,
),
],
),
Padding(
padding: const EdgeInsets.only(
left: 100, right: 100, top: 50, bottom: 50),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: SizedBox(
height: 50,
child: Center(
child: Text(
'order pics & clips',
style: TextStyle(color: Colors.white),
)),
),
onPressed: () {
print(name);
print(email);
print(account);
},
),
),
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, i) {
return Column(
children: [
ProfilePost(
snapshot.data.documents[i]['url'],
snapshot.data.documents[i]['likes'].toString(),
snapshot.data.documents[i]['donations']
.toString())
],
);
}),
],
);
}),

You could use the shrinkWrap: true property on the ListView() and ListView.builder() widgets so that the total size (height) of the listview is the sum of the heights of the children.

Related

ListView inside Alert Dialog displays empty transparent window

Below is my Alertdialog:
return AlertDialog(
title: const Text('Choose Device'),
content: ListView.builder(
shrinkWrap: true,
itemCount: listDevices.length,
itemBuilder: (_, int index) => deviceList(listDevices[index]),
),
);
Below is deviceList function:
Widget deviceList(String strDevice) => SizedBox(
height: 150.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
const Icon(Icons.toys),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(strDevice),
),
],
),
const SizedBox(
height: 20.0,
),
],
),
);
Its not displaying Listview and am getting error as:
The following assertion was thrown during paint():
RenderBox was not laid out: RenderPhysicalShape#aedc0 relayoutBoundary=up2
'package:flutter/src/rendering/box.dart':
Failed assertion: line 2001 pos 12: 'hasSize'
What might be the issue? Thanks.
You can use like this:
List<String> listDevices = <String>['iPhone 11', 'Samsung M22f', 'MacBook Pro', 'Xiaomi note 12 pro'];
I opened AlertDialog box when tap on ElevatedButton like this:
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text("Alert Dialog Box"),
content: SizedBox(
// height: 250,
width: 150,
child: ListView.builder(
shrinkWrap: true,
itemCount: listDevices.length,
itemBuilder: (_, int index) => deviceList(listDevices[index]),
),
),
),
);
//onTap function define here
},
child: const Text('Send Message'),
),
I don't changes your deviceList widget
And i clearly show AlertDialogBox with ListView. I hope it's help you.
Happy Coding :}
Try to wrap ListView.builder in a SizedBox with a specific height and width.
AlertDialog(
title: const Text('Choose Device'),
content: SizedBox(
height: 300,
width: 300,
child: ListView.builder(
shrinkWrap: true,
itemCount: listDevices.length,
itemBuilder: (_, int index) =>
deviceList(listDevices[index]),
),
),
),

Flutter: Make all screen scrollable with GridView.builder inside

In my home screen my app shows carousel first then a vertical list of challenges cards retrieved from Cloud Firestore using GridView.builder as follows:
GridView.builder(
scrollDirection: Axis.vertical,
itemCount: _challenges.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),
),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
if (_challenges[index]["isLocked"] == "true") {
showLockedDialog();
} else {
checkParticipation(index);
if (checkPart == true) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
ChallengeDetails(_challenges[index])));
}
checkPart = true;
}
},
child: Stack(
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image: NetworkImage(_challenges[index]["image-path"]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: _challenges[index]["isLocked"] == "true"
? AlwaysStoppedAnimation(.4)
: null,
),
),
),
Center(
child: Text(
"${_challenges[index]["name"]}\n",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
"\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
textDirection: TextDirection.ltr,
)),
Center(
child: SizedBox(
height: 130,
width: 130,
child: _challenges[index]["isLocked"] == "true"
? Image.asset("assets/lock-icon.jpg")
: null,
),
)
],
),
);
});
Everything retrieving fine and it is rendered in my home_screen as follows:
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(right: 8, left: 8, bottom: 5),
child: Row(
children: [
Text(
AppLocalizations.of(context)!.challenges + " ",
style: TextStyle(fontSize: 20),
),
Text(
AppLocalizations.of(context)!.clickToParticipate,
style: TextStyle(fontSize: 15),
)
],
),
),
Expanded(child: ChallengeCard()),
],
),
The problem is that only the GridView area is scrolling and what am seeking for is to scroll the whole screen with the GridView area, I was trying to use the CustomScrollView() but its not working properly.
I'll be thankful for any help.
First in your GridView.builder add these:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
...
)
then in your home_screen wrap your column with SingleChildScrollView:
SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
...
),
),
You can provide physics: NeverScrollableScrollPhysics() on GridView to disable scroll effect. If you want scrollable as secondary widget use primary: false, to have Full Page scrollable, you can use body:SingleChildScrollView(..) or better using body:CustomScrollView(..)

Flutter - ListView nested in columns gives error "hasSize"

I have a ListView.builder() nested inside multiple columns, I get the following error and the widget doesn't build at all due to this:
════════ Exception caught by rendering library
═════════════════════════════════ RenderBox was not laid out:
RenderShrinkWrappingViewport#813d4 relayoutBoundary=up40 NEEDS-PAINT
NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
package:flutter/…/rendering/box.dart:1 Failed assertion: line 1982 pos
12: 'hasSize'
The relevant error-causing widget was ListView
lib\…\Widgets\todolistmodule_briefcard.dart:81
Below is the code:
class TodolistModuleBriefCard extends StatelessWidget {
//const NotesBriefModule({ Key? key }) : super(key: key);
TodolistModule todolistModule;
TodolistModuleBriefCard({required this.todolistModule});
#override
Widget build(BuildContext context) {
return buildCard();
}
Widget buildCard() => Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Container(
child: Card(
color: Color.fromARGB(255, 240, 240, 240),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: buildContent(),
),
),
);
Widget buildContent() => Column(
children: [
buildName(),
Divider(
height: 1,
),
buildTodoList()
],
);
Widget buildName() => Padding(
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 15),
child: Text(
todolistModule.name,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontFamily: AppConfig.primaryFontFamily,
fontSize: 17,
color: Colors.grey.shade700,
fontWeight: FontWeight.w500,
),
),
);
Widget buildTodoList() => Padding(
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildTodoListSubList(
subList: todolistModule.todo, subListTitle: "To Do"),
buildTodoListSubList(
subList: todolistModule.completed, subListTitle: "Complete")
],
),
);
Widget buildTodoListSubList(
{required List<String> subList, required String subListTitle}) =>
Column(
children: [
buildTodoListSubListTitle(title: subListTitle),
buildTodoListSubListItems(subList: subList),
],
);
Widget buildTodoListSubListTitle({required String title}) => Text(
title,
style: TextStyle(fontFamily: AppConfig.primaryFontFamily),
);
Widget buildTodoListSubListItems({required List<String> subList}) =>
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: subList.length,
itemBuilder: ((context, index) {
return buildTodoListSubListItem(item: subList[index]);
}),
);
Widget buildTodoListSubListItem({required String item}) => Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text(item,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 3,
style: TextStyle(
fontFamily: AppConfig.primaryFontFamily, fontSize: 13)),
),
);
}
Could someone please help me solve this problem?
just add Expanded
Widget buildTodoList() => Padding(
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: buildTodoListSubList(
subList: todolistModule.todo, subListTitle: "To Do"),
),
Expanded(
child: buildTodoListSubList(
subList: todolistModule.completed, subListTitle: "Complete"),
)
],
),
);
But you need read more about the layout principle
there is two solution:
you can surround your ListView with a container with a certain height like a height of your screen from media query for example:
Column(children: [
Container(
width: double.infinity,
height: 400,
child: ListView.builder(
itemBuilder: (context, index) {
return Container(
width: 200,
height: 890,
color: Colors.red,
child: Text('Hello'),
);
},
itemCount: 1,
),
)
]),
the second solution but I think it will stop the scrollable but try it is to set shrinkWrap property in listView to true like this:
Column(children: [
ListView.builder(
shrinkWrap: true, // this is shrinkWrap property!!!
itemBuilder: (context, index) {
return Container(
width: 200,
height: 400,
color: Colors.red,
child: Text('Hello'),
);
},
itemCount: 1,
)
]),

Snapshot from StreamBuilder

I am working on a ListView inside a Streambuilder with data from Cloud Firestore.
Here you have the code:
//inicio stream
StreamBuilder<List<Evento>>(
stream: eventosProvider
.eventosbares,
builder: (context, snapshot) {
if (snapshot
.data.isNotEmpty) {
return SizedBox(
height: 155,
child: ListView.builder(
scrollDirection:
Axis.horizontal,
itemCount: snapshot
.data.length,
itemBuilder:
(context,
index) {
var dateString =
snapshot
.data[
index]
.fechaEvento;
var date = DateFormat(
'd-M-yyyy HH:mm',
'de_DE')
.parse(
dateString);
return Card(
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
10),
),
child:
Container(
height: 178,
width: 280,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 8.0,
right: 8.0,
top: 8.0),
child:
ClipRRect(
borderRadius:
BorderRadius.circular(8),
child:
Image.network(
snapshot.data[index].imagenEvento,
width: 278.0,
height: 80.0,
fit: BoxFit.fill,
),
),
),
Padding(
padding:
const EdgeInsets.all(8.0),
child:
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
CircleAvatar(
radius: 20.0,
backgroundImage: NetworkImage(snapshot.data[index].fotoPerfilAutor),
backgroundColor: Colors.transparent,
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: 150,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
snapshot.data[index].tituloEvento,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
Text(
DateFormat('EEEEE dd MMM yyyy HH:mm', 'es_ES').format(date),
style: TextStyle(fontSize: 10),
),
],
),
),
),
SizedBox(
width: 10,
),
Text(
snapshot.data[index].num_invitados,
style: TextStyle(color: ColoresApp.naranjaTop, fontWeight: FontWeight.bold, fontSize: 14),
),
SizedBox(
width: 5,
),
CircleAvatar(
radius: 10.0,
backgroundImage: AssetImage("assets/friends.png"),
backgroundColor: Colors.transparent,
)
],
),
),
]),
),
);
}),
);
} else {
return Text(
"No hay eventos en bares",
style: TextStyle(
color:
Colors.white),
);
}
}),
I am getting the following exception using this code, the app is not exiting, it only shows a red error background for a moment, but it is not acceptable:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building StreamBuilder<List<Evento>>(dirty, state: _StreamBuilderBaseState<List<Evento>, AsyncSnapshot<List<Evento>>>#d6fd3):
The getter 'isNotEmpty' was called on null.
Receiver: null
Tried calling: isNotEmpty
I have tried changing the line:
if (snapshot.data.isNotEmpty)
with
if (snaphot.hasData)
but then, the exception is gone, but there is a blank space thrown, not the else part of the if clause.
What should I do to know if the snapshop has really data or is waiting to get them?
EDIT
Here you have the service loading the Stream:
Stream<List<Evento>> getEventosBares(){
return _db
.collection('eventos').where('interes', isEqualTo: 'bares')
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Evento.fromJson(doc.data()))
.toList());
}
And here you have the provider:
Stream<List<Evento>> get eventosbares => firestoreService.getEventosBares();
Try adding a null check:
builder: (context, snapshot) {
if (snapshot.data != null && snapshot.data.isNotEmpty) {
return SizedBox(...);

How to use Expanded with Future

Part of my code is as follows:
Expanded(
flex: 13,
child: Container(
padding: EdgeInsets.all(2),
color: Colors.black12,
child: FutureBuilder(
future: getCompromissos(),
builder: (context, snapshot) {
if (compromissosFiltrados != null && compromissosFiltrados.compromissos.length > 0) {
return ListView.builder(
controller: ScrollController(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: compromissosFiltrados.compromissos.length,
itemBuilder: (context, index) {
return CompromissoCard(
indice: index,
title: compromissosFiltrados.compromissos[index].nome,
icon: new Icon(icons[0], size: 24.0, color: Colors.green));
},
);
} else {
return Container();
}
},
),
),
),
Sometimes getCompromissos() does not return any item and I have that empty space in my app.
I would like Expanded occupied all the space when there are nothing to show, like this:
In the lower part Expanded( flex: 0 is working because contents of that widget don't come from the web.
But in this widget if I use flex : 0 and there's not item, it's ok, but if there are items then I have errors like this:
RenderBox was not laid out: RenderRepaintBoundary#6c79b
relayoutBoundary=up6 NEEDS-PAINT
'package:flutter/src/rendering/box.dart': Failed assertion: line 1694
pos 12: 'hasSize'
In case you need that part of CompromissoCard
return new Container(
color: Colors.white12,
child: new Card(
child: Container(
color: Colors.white30,
padding: new EdgeInsets.only(left: 5, top: 5, bottom: 5, right: 10),
child: new Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(height: 15),
Column(children: <Widget>[new Image.asset("assets/images/meeting.png")])
]),
Column(children: <Widget>[
Row(
children: <Widget>[
Column(children: <Widget>[
SizedBox(
height: 15,
),
Text("13:00 - 14:00", style: TextStyle(color: Colors.black38, fontSize: 16)),
SizedBox(
height: 5,
),
Text(this.title, style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w300))
]),
],
),
])
]),
),
));
I can't figure out how to do this.
Someone could help me? Thanks in an advance.