ExpansionPanelList Scroll Issue - flutter

I have an ExpansionPanelList inside a ListView and I'm unable to get it to scroll when trying in the middle of the screen, though it will work on the edges. I've attached the code below. I'm guessing its the ExpansionPanelList that isn't letting me scroll but I'm not sure why because the items are inside a ListView as well.
I've taken a video of the issue https://drive.google.com/file/d/19zM7cfjshcN8OfEbRhvxIgmUp8sq1TP6/view?usp=sharing
_bodyBuilder() {
return
ListView(
shrinkWrap: true,
padding: EdgeInsets.all(15.0),
children: <Widget>[
ExpansionPanelList.radio(
initialOpenPanelValue: 2,
children: dateList.map<ExpansionPanelRadio>((DateTime date) {
return ExpansionPanelRadio(
canTapOnHeader: true,
value: date.day,
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(DateFormat('dd/MM/yyyy').format(date)),
);
},
body: Container(
//child: ListView.separated(
child: ListView.builder(
shrinkWrap: true,
itemCount: cleanRecords
.where((Log) =>
DateTime.parse(DateFormat('yyyy-MM-dd')
.format(Log.time.toDateTime()))
.toString() ==
date.toString())
.toList()
.length,
itemBuilder: (context, index) {
final records = cleanRecords
.where((Log) =>
DateTime.parse(DateFormat('yyyy-MM-dd')
.format(Log.time.toDateTime()))
.toString() ==
date.toString())
.toList();
final schedule = records[index];
return ListTile(
title: Text(DateFormat('hh:mm').format(schedule.time.toDateTime())),
subtitle: Text(schedule.notes),
onTap: () => _updateRecord(schedule.parentID, schedule.id),
);
},
// separatorBuilder: (context, index) {
// return Divider();
// },
),
),
);
}).toList(),
)
],
);// ListTiles++
}

Related

Flutter: RenderFlex overflow when using column

I'm getting a renderflex overflow error which displays as the following:
It's coming from the following code:
return Column(
children: [
DropdownButton<String>(
items: Utils.ddsDropdown
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (value) {}),
ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(0, 16, 0, 16),
itemCount: card.length,
itemBuilder: (context, index) {
return MyCard.buildCard(card[index], context);
},
)
],
)
I also tried to wrap the column in an Expanded widget and in a SingleChildScrollView but still got the same error. I think the column is preventing the page from being fully scrollable. But I need the column to be able to have the DropdownButton and ListView.
I even tried wrapping the entire widget in a SingleChildScrollView as follows:
Widget build(BuildContext context) => SingleChildScrollView(
child: FutureBuilder<List<Map<String, dynamic>>>(
future: MyCard.getData(widget.categoryIndex, widget.subCategories)!
.whenComplete(() => setState(() {
isLoading = false;
})),
builder: ((context, snapshot) {
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
return FutureBuilder<List<MyCard>>(
future: MyCard.readData(snapshot.data),
builder: (context, cards) {
if (cards.hasData) {
final card = cards.data!;
return Column(
children: [
//Text("Hello"),
DropdownButton<String>(
items: Utils.ddsDropdown
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (value) {}),
ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(0, 16, 0, 16),
itemCount: card.length,
itemBuilder: (context, index) {
return MyCard.buildCard(card[index], context);
},
)
],
);
} else {
return const Text("No data");
}
});
} else {
return isLoading
? Column(
children: const [CircularProgressIndicator()],
)
: const Text("You do not have any workouts yet");
}
}),
));
but it still overflows.
Wrap only the ListView in Expanded as follows:
Column(
children: [
DropdownButton<String>(
...
Expanded(
child: ListView.builder(
...
This other answer will provide you with further details about your question.
Use SingleChildScrollView to use a scrollable area of that column as below:
return SingleChildScrollView(
child: Column(
children: [
DropdownButton<String>(
items: Utils.ddsDropdown
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (value) {}),
ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(0, 16, 0, 16),
itemCount: card.length,
itemBuilder: (context, index) {
return MyCard.buildCard(card[index], context);
},
)
],
)
I hope this solved your problem.

What is wrong, I've used the relevant GetX widget and it still throws this error

This is the code where the error occurred using GetX. If anyone want to help thanks for advance
body: SafeArea(
child: Column(
children: [
Expanded(
child: GetX<CustomerController> (
builder: (customerController) {
return ListView.builder(
itemCount: customerController.count,
itemBuilder: (context, index) {
return ListTile(
selectedTileColor:Colors.blueGrey.shade50,
title: Text(customerController.results.string),
);
});
},
),
)
],
),
),
Create a GetX Controller and then assign it to your GetX Widget
GetX<ControllerName>(
builder: (customerController) {
return ListView.builder(
itemCount: customerController.controllervalueinobx.length, //should be obx/Rx type variable
itemBuilder: (context, index) {
return ListTile(
selectedTileColor: Colors.blueGrey.shade50,
title: Text(
"customerController.results.string",
), );
});
},
),

Flutter List view builder doesn't shrink when Keyboard appears

I'm creating a chat feature in flutter but noticed this behavior on IOS that doesnt shrink the list so you can see the last sent message. How can I have the listview builder shrink to show the last message when the keyboard appears?
Note: This issue doesn't happen on Android
Scaffold(
resizeToAvoidBottomInset: true,
body: Stack(
children: <Widget>[
StreamBuilder(
stream: _chats,
builder: (context, snapshot) {
if (!snapshot.hasData) return Container();
return snapshot.hasData
? GestureDetector(
onPanDown: (_) {
FocusScope.of(context).requestFocus(FocusNode());
},
child: ListView.builder(
shrinkWrap: true,
controller: _scrollController,
padding: EdgeInsets.only(top: 10, bottom: 100),
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return MessageWidget(
tripId: widget.docId,
uid: snapshot.data.docs[index].data()["uid"],
messageId: snapshot.data.docs[index].id,
message: snapshot.data.docs[index].data()["message"],
sender: snapshot.data.docs[index].data()["senderName"],
sentByMe: widget.uid ==
snapshot.data.docs[index].data()["uid"],
mediaFileUrl:
snapshot.data.docs[index].data()["mediaFileUrl"],
);
}),
)
: Container();
},
);
]
)
)
I think you can try the 'reverse' property from the ListView.builder.
Tell me if this example didn't fit your needs, can you share us your code ? (I didn't see why you use a Stack and what could be the issue around that).
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: Stack(
children: <Widget>[
StreamBuilder<dynamic>(
builder: (context, dynamic snapshot) {
return GestureDetector(
onPanDown: (_) {
FocusScope.of(context).unfocus();
},
child: ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: 100,
padding: const EdgeInsets.only(top: 10, bottom: 10),
itemBuilder: (context, index) {
return ListTile(title: Text(index.toString()));
},
),
);
},
),
],
),
),
Container(
padding: const EdgeInsets.all(8),
color: Colors.black12,
child: const TextField(),
),
],
),
);
}
}

Flutter Visibility widget not working third time

I have wrapped ListView.builder inside Visible widget, and the button for its visible property is in a ListTile widget with variable _currencyVisible.
The widget Visible works 2 times i.e. false/hidden(default), then changes to visible when clicked, and again hides on the second click, but it doesn't work after that. Printing on console _currencyVisible shows correct data.
Here's my code:
menuItems(BuildContext context) {
bool _currencyVisible = false;
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListView(
children: [
ListTile(
title: FutureBuilder<dynamic>(
future: getUserCurrencySymbol(),
builder:(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
return Text("Currency " + snapshot.data.toString());
}),
trailing: IconButton(
icon: Icon(Icons.refresh),
onPressed: () { setState(() { _currencyVisible = !_currencyVisible; }); },
),
),
Visibility(
visible: _currencyVisible,
child: ListView.builder(
shrinkWrap: true,
itemCount:
currency.allCurrenciesList.length,
itemBuilder: (context, index) {
for (Currency c in currency.allCurrenciesList) {
currency.allCurrenciesList.removeAt(0);
return Card(
child: ListTile(
title: Text(c.country),
subtitle: Text(c.shortCurrency),
trailing: Text(c.symbol),
onTap: () {
saveUserCurrency(c.country, context);
},
),
);
}
return Text("Not Null");
},
),
),
],
);
},
);
}
You are removing all of the data from your currency list. The widget is showing correctly, but there is no data to display.
Remove this line
currency.allCurrenciesList.removeAt(0);
Don't loop through the currencies in itemBuilder. Use index instead.
Visibility(
visible: _currencyVisible,
child: ListView.builder(
shrinkWrap: true,
itemCount: currency.allCurrenciesList.length,
itemBuilder: (context, index) {
final c = currency.allCurrenciesList[index];
return Card(
child: ListTile(
title: Text(.country),
subtitle: Text(c.shortCurrency),
trailing: Text(c.symbol),
onTap: () {
saveUserCurrency(c.country, context);
},
);
}
return Text("Not Null");
),
),

flutter: randomize item count in list View

i implemented listView in flutter and it shows product count=5 , but i wanted these 5 items to be generated randomly , is there a way to do it? thanks in advance
ps: i tried code depending on answer below but it gives me error count!=null
Expanded(
child: SizedBox(
height: 210.0,
child: FutureBuilder(
future: httpService.getProducts(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text('Loading...'),
),
);
} else if (snapshot.data.length == 0) {
return Container(
child: Center(
child: Center(
child: Text('No offers'),
),
),
);
} else {
var rndItems = snapshot.data.shuffle();
return ListView.separated(
separatorBuilder:
(BuildContext context, int index) {
return SizedBox(height: 3);
},
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: rndItems ,
itemBuilder: (ctx, i) => (PdtItem(
title: snapshot.data[i].title,
imgUrl: snapshot.data[i].imgUrl,
price: snapshot.data[i].price,
pdt2: snapshot.data[i])),
);
If you want the items from snapshot.data to be listed in a random order then you may shuffle the data as follows :
....
snapshot.data.shuffle();
....
If you want to display random number of items everytime then
....
import 'dart:math';
....
var rng = new Random();
var rndItems = rng.nextInt(snapshot.data.length);
....
.....
scrollDirectionn: Axis.horizontal,
shrinkWrap: true,
itemCount: rndItems,
itemBuilderr: (ctx, i) => (PdtItem(
.....