Not able to nest list in ExpansionTileCard in flutter - flutter

I am trying to nest listview.builder in ExpansionTileCard but not able to do so I am getting this error
ERROR
The following assertion was thrown during performResize():
Vertical viewport was given unbounded height.
CODE
ExpansionTileCard(
leading: GestureDetector(
onTap: (){
var firstdata = jsonResponse['content'];
code = firstdata[index]['code'];
},
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.asset('images/appicon.png', width: 50, height: 50)),
),
title: GestureDetector(
onTap: (){
var firstdata = jsonResponse['content'];
code = firstdata[index]['code'];
name = firstdata[index]['name'];
Navigator.push(context, MaterialPageRoute(builder: (context) =>PageViewClass(companycode: code,userid: widget.userid,)));
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(firstdata[index]['name'] ?? 'NULL PASSED'),
],
),
),
children: <Widget>[
Divider(
thickness: 1.0,
height: 1.0,
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 8.0,
),
child:ListView.builder(
itemCount: list1.length,
itemBuilder: (BuildContext ctx, int index){
return Text(list1[index]['name']);
}
)
),
),
],
);
TheExpansionTileCard is already used in a parent Listview.builder .
Please guide me to resolve this issue

In Listview.builder you can try to keep shrinkWrap: true,
and in Column Widget, you can keep mainAxisSize = MainAxisSize.min,
A combination of this both should do the trick.

Related

When keyboard open/close at that time ChangeNotifierProvider call multiple time

I am facing issue When keyboard open/close at that time ChangeNotifierProvider call multiple time so my full screen reload multiple time. In this widget I have attach video so widget is calling so many times then my instance is fail.
return Scaffold(
backgroundColor: ColorManager.colorBackgroundGray,
body: ChangeNotifierProvider<CreateRouteStep2ViewModel>(
create: (BuildContext context) => modelProvider,
builder: (context, snapshot) {
printValue(label: "ChangeNotifierProvider", value: "");
return Consumer<CreateRouteStep2ViewModel>(
builder: (context, provider, c) {
return SizedBox(
height: double.infinity,
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
provider.viewType == CreateRouteStep2ViewType.map
? SizedBox(
height: 300,
child: GoogleMapForCreateRoute(
modelProvider: modelProvider),
)
: const SizedBox(),
],
),
)
],
),
Expanded(
flex: 1,
child: Container(
color: ColorManager.colorWhite,
child: SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
physics:
const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 10),
itemCount: provider.listRouteName.length,
itemBuilder: (BuildContext context, index) {
return CreateStepsItem(
routeModel:
provider.listRouteName[index],
modelProvider: modelProvider,
index: index,
removeIndex: () {
// Todo Remove index from marker pin and location array.
modelProvider
.removeIndexFromPinAndList(index);
},
edtLocationNameFocus: () {
modelProvider.focusMap(index);
},
edtAudioFocus:
(mainPosition, subPosition) {
modelProvider.focusAudioComponent(
index, subPosition);
},
edtVideoFocus:
(mainPosition, subPosition) {
modelProvider.focusVideoComponent(
index, subPosition);
},
);
},
scrollDirection: Axis.vertical,
),
),
)),
Visibility(
visible:
MediaQuery.of(context).viewInsets.bottom == 0,
child: Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(
left: 24.0, right: 24.0, bottom: 20.0),
child: CommonButton(
onPressed: () {},
lable: AppStrings.constTourSpichern,
isEnable: false,
),
),
),
)
],
),
),
const SizedBox(
height: 20,
)
],
),
);
});
}),
);
Is there any widget behaviour is attach with keyboard?. If any one know that then please let me know.

Flutter error:Failed assertion: line 1785 pos 12: 'hasSize'

I have a code of recording Audio in flutter. The code should work perfectly without errors, whenever I try to call it from an alert dialog I end up with an error
The following assertion was thrown during performLayout():
RenderShrinkWrappingViewport does not support returning intrinsic
dimensions.
Calculating the intrinsic dimensions would require instantiating every
child of the viewport, which defeats the point of viewports being
lazy.
If you are merely trying to shrink-wrap the viewport in the main axis
direction, you should be able to achieve that effect by just giving
the viewport loose constraints, without needing to measure its
intrinsic dimensions.
Am trying to pass an option to record audio to an alert dialog. Users to record audio from a pop up instead of a main screen. What am I doing wrong?
What i have so far
Widget setupAlertDialoadContainer() {
return ListView(
shrinkWrap: true, //just set this property
padding: const EdgeInsets.all(8.0),
//children: listItems.toList(),
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 24.0, bottom: 16.0),
child: Text(
this._recorderTxt,
style: TextStyle(
fontSize: 48.0,
color: Colors.black,
),
),
),
_isRecording
? LinearProgressIndicator(
value: 100.0 / 160.0 * (this._dbLevel ?? 1) / 100,
valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
backgroundColor: Colors.red,
)
: Container()
],
),
Row(
children: <Widget>[
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(10.0),
child: FloatingActionButton(
heroTag: "Record",
onPressed: () {
if (!this._isRecording) {
return this.startRecorder();
}
this.stopRecorder();
},
child: this._isRecording ? Icon(Icons.stop) : Icon(Icons.mic),
),
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 60.0, bottom: 16.0),
child: Text(
this._playerTxt,
style: TextStyle(
fontSize: 48.0,
color: Colors.black,
),
),
),
],
),
Row(
children: <Widget>[
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(8.0),
child: FloatingActionButton(
heroTag: "Start",
onPressed: () {
startPlayer();
},
child: Icon(Icons.play_arrow),
),
),
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(8.0),
child: FloatingActionButton(
heroTag: "Pause",
onPressed: () {
pausePlayer();
},
child: Icon(Icons.pause),
),
),
Container(
width: 56.0,
height: 56.0,
margin: EdgeInsets.all(8.0),
child: FloatingActionButton(
heroTag: "Stop",
onPressed: () {
stopPlayer();
},
child: Icon(Icons.stop),
),
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
Container(
height: 56.0,
child: Slider(
value: slider_current_position,
min: 0.0,
max: max_duration,
onChanged: (double value) async {
await flutterSound.seekToPlayer(value.toInt());
},
divisions: max_duration.toInt()))
],
);
}
How am passing the data to the Alert dialog
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Record the data collection'),
content: setupAlertDialoadContainer(),
);
});
is the error is showing when alert box is opened??
if yes my suggestion is using
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Record the data collection'),
content: Container(
child:setupAlertDialoadContainer(),
height:200,
width:200,
),
);
});
change the width and height of container according to your need

ListView inside a Row with dynamic width

I want to create a ListView and a Button to add items to the ListView.
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
Conversation conversation = teamMembers[index];
return SizedBox(
width: 42,
height: 42,
child: Avatar(
name: member.name,
profileUrl: member.profileUrl,
radius: 38,
),
);
},
itemCount: teamMembers.length,
),
),
InkWell(
onTap: () {
_showSheet();
},
child: Container(
width: 42,
height: 42,
decoration: new BoxDecoration(
color: Color(0xfff2f2f2),
borderRadius: BorderRadius.circular(28)),
child: Icon(Icons.add),
),
),
],
)
I'm getting the results as below for lesser number of items and more number of items. How can I make the + button closer to the ListView even if the list length is less.
List<Widget> _buttons = [];
Wrap(
spacing: 12.0, // horiz
runSpacing: 12.0, // vert
crossAxisAlignment: WrapCrossAlignment.start,
alignment: WrapAlignment.start,
children: _buttons,
),
The solution to this issue is replacing the Expanded widget with Flexible widget.
Expanded actually is just a shorthand for Flexible. Flexible takes only the needed space, and Expanded takes all available space, respecting the flex factor.
Flexible with fit: FlexFit.loose which is the default one solves the problem. If the fit is FlexFit.loose, the child can be at most as large as the available space (but is allowed to be smaller)
So,
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
Conversation conversation = teamMembers[index];
return SizedBox(
width: 42,
height: 42,
child: Avatar(
name: member.name,
profileUrl: member.profileUrl,
radius: 38,
),
);
},
itemCount: teamMembers.length,
),
),
InkWell(
onTap: () {
_showSheet();
},
child: Container(
width: 42,
height: 42,
decoration: new BoxDecoration(
color: Color(0xfff2f2f2),
borderRadius: BorderRadius.circular(28)),
child: Icon(Icons.add),
),
),
],
)
is the solution.

How to make a bottom sheet with height follow the amount of item of JSON

BottomSheet in Flutter so that the height follows the number of items (data from JSON) is that what? Because I made the height not follow the amount of data but followed 1/2 the screen of each cellphone. So if the phone is long, there is empty space at the bottom. If the cellphone is short, the data is cut by the screen below.
This is the code for creating bottom sheet:
void _showModalBottomSheet(AsyncSnapshot<CatlistResult> snapshot) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15))),
child: Container(
padding: EdgeInsets.only(left: 16.0, top: 10.0, right: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 10.0),
child: Image.asset('assets/images/main/more_2lines_20dp.png', scale: 3.5),
),
Expanded(
child: GridView.builder(
physics: NeverScrollableScrollPhysics(), //kill scrollable
shrinkWrap: true,
itemCount: snapshot == null ? 0 : snapshot.data.catlist.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (BuildContext context, int index) {
var numItems = snapshot.data.catlist[index];
if (numItems.f == 1) {
if (numItems.b == 0) {
return GestureDetector(
child: Card(
elevation: 0.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Image.asset('assets/images/main/cat_${numItems.a}.png', fit: BoxFit.cover, width: 50.0, height: 50.0),
Container(
margin: EdgeInsets.only(top: 10.0),
child: Text(
numItems.c,
maxLines: 2,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 10),
),
),
],
),
),
);
}
}
},
),
),
],
),
),
);
}
);
}
And this is the result of my code:
Run from iOS Emulator
Run from Android Emulator
Problems:
In your parent Column you are using
mainAxisSize: MainAxisSize.max
You are also using Expanded in this Column which creates the empty space if there are less items in the GridView. Remove this Expanded widget.
Solution:
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // 1st use min not max
children: <Widget>[
Container(...),
GridView.builder(...), // 2nd remove Expanded
],
)

Flutter dynamic height of ListView

I am developing a Flutter application and I want to dynamically adjust the height of the ListView.
I want the list to have a maximum height of 200. If the height is more than that, user will have to scroll to reach the bottom. If height is below 200, it will take only as much space as needed.
Preview of application: Screenshot. As you can see Restaurants nearby is pushed to the very bottom of the page. I want the ListView to only take height of 200 or less so that the content below isn't pushed to the bottom.
Here is my current code:
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Restaurants nearby',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('Enter restaurant manually'),
onPressed: () {
print('Button pressed');
},
),
],
),
Flexible(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.cyan,
),
title: Text('Test restaurant'),
subtitle: Text('80m'),
);
},
itemCount: 15,
),
),
Text(
'Restaurants nearby',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
],
),
);
}
You are using Flexible widget, that's why your ListView expands. You have to change Flexible to ConstrainedBox and add shrinkWrap: true to your ListView.
ConstrainedBox(
constraints: BoxConstraints(maxHeight: 200, minHeight: 56.0),
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.cyan,
),
title: Text('Test restaurant'),
subtitle: Text('80m'),
);
},
itemCount: 15,
),
),
More info here: https://api.flutter.dev/flutter/widgets/ConstrainedBox-class.html
You can use LimitedBox
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(...),
Divider(),
Row(...),
LimitedBox(
maxHeight: 200.0,
child: ListView.builder(...),
),
Text(...),
],
),
Recommended solution in case when the incoming constraints are unbounded
Consider wrapping the ListView into this
LimitedBox(
maxHeight: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.cyan,
),
title: Text('Test restaurant'),
subtitle: Text('80m'),
);
},
itemCount: _itemsCount,
),
),
]
)
),
Note that:
shrinkWrap of ListView is set to true
mainAxisSize of Column is set to MainAxisSize.min
maxHeight of LimitedBox is set to 200
A complete snippet:
import 'package:flutter/material.dart';
class DebugWidget extends StatefulWidget {
#override
_DebugWidgetState createState() => _DebugWidgetState();
}
class _DebugWidgetState extends State<DebugWidget> {
int _itemsCount = 1;
#override
Widget build(BuildContext context) {
Widget child = Container(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Restaurants nearby',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('Enter restaurant manually'),
onPressed: () {
print('Button pressed');
},
),
RaisedButton(
child: Text('+1'),
onPressed: () {
setState(() {
_itemsCount += 1;
});
},
),
RaisedButton(
child: Text('-1'),
onPressed: () {
setState(() {
_itemsCount -= 1;
});
},
),
],
),
LimitedBox(
maxHeight: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.cyan,
),
title: Text('Test restaurant'),
subtitle: Text('80m'),
);
},
itemCount: _itemsCount,
),
),
]
)
),
Text(
'Restaurants nearby',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
],
),
);
return Scaffold(
body: child,
);
}
}
I found a solution to this problem. you should wrap your ListView with LimittedBox or ConstraintBox and give them maxHeight and set shrinkWrap property of ListView to true. the solution would be something like this.
LimitedBox(
maxHeight: 200,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.cyan,
),
title: Text('Test restaurant'),
subtitle: Text('80m'),
);
},
itemCount: 15,
),
),
I see that this question has never been answered only with giving a fixed height, so here is what works for me.
For some reason if you set the shrinkwrap to true it doesn't look like it is working but it does, the problem is in the padding settings of the ListView, set the padding to edgeinstets.zero. That fixes it for me.
Wrap inside a Flexible
ShrinkWrap true
Padding, zero
and if needed the column to MainAxisSize.min.
Hope it helps some people.
Example of my code:
Flexible(
child: Container(
decoration: BStyles.cardDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'PRODUCTION TASKS',
),
const SizedBox(
height: textVerticalSpacing,
),
Flexible(
child: ListView.builder(
itemCount: recentTasks.length,
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return TaskCard(
task: recentTasks[index],
widthInfo: MediaQuery.of(context).size.width * 0.6,
);
},
),
),
const SizedBox(
height: itemSpacing,
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () { },
child: const Text(
'View more',
),
),
),
const SizedBox(
height: textVerticalSpacing,
),
],
),
),
),
),
ConstrainedBox(
constraints: BoxConstraints(maxHeight: 200.0),
child: [your child here],
)
This make your child's height not bigger than 200.0
You can always size the ListView container as % of the viewport (assuming of course that the other widgets also are sized in the same manner):
return Container(
height: MediaQuery.of(context).size.height * 0.75,
child: ListView.builder(
itemBuilder: (ctx, index) {
return Card(...