I am displaying the records on ListView using ListView.builder from api response data, i want to delete the list item when user click on icon, here is the code
Container(
child:SingleChildScrollView(
scrollDirection: Axis.vertical,
child: FutureBuilder(
future: _getRecord(), //getting data from this method
builder: (BuildContext context,
AsyncSnapshot<List<History>> snapshot) {
if (snapshot.hasData) {
if(historyList.length!=0){
return Container(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child:Expanded(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child:Stack(
overflow: Overflow.visible,
children: <Widget>[
ListTile(
leading: CircleAvatar(
radius: 25,
backgroundColor:Color(int.parse(annualboxcolor))
child: Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
child:Column(children: <Widget>[
Text(dateObj.day.toString()),
]
),
)),
title: Text(snapshot.data[index].username),
isThreeLine: true,
subtitle:
IconButton(icon:Icon(Icons.check_box,color: Colors.green,size: 30,),onPressed: (){})]) //i want to delete item on click on this icon
please help how to do this.
You can use below line in onTap event of ListTile Widget.
setState(() {
snapshot.data.removeAt(index);
});
Related
I am new to flutter and would appreciate if someone could give me some hints on this:
I have to make few (not fixed number of) widgets which have to be expandable.
When expanded, they contain list of widgets in their body. List is long and it has to be scrollable in order to see all items.
If I put everything (whole expandable widget) inside SingleChildScrollView list items in body are scrollable, but also headers scroll - which I should prevent.
Widget _buildPanel() {
return SingleChildScrollView(
child: ExpansionPanelList.radio(
children: _data.map<ExpansionPanelRadio>((Item item) {
return ExpansionPanelRadio(
value: item.id,
headerBuilder: (BuildContext context, bool isExpanded) {
return Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Row(
children: [
SvgPicture.network(
"https://some_picture.svg",
height: 80),
Column(children: <Widget>[
Text(' Some Text'),
Text(' label '),
]),
],
));
},
body: ListView.builder(
itemCount: widgets.length,
itemBuilder: (context, index) => ListTile(title: widgets[index]),
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
));
}).toList(),
));
}
and if I put only body inside SingleChildScrollView like this, then I got Exceptions.
Widget _buildPanel() {
return ExpansionPanelList.radio(
children: _data.map<ExpansionPanelRadio>((Item item) {
return ExpansionPanelRadio(
value: item.id,
headerBuilder: (BuildContext context, bool isExpanded) {
return Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Row(
children: [
SvgPicture.network("https://some_picture.svg",
height: 80),
Column(children: <Widget>[
Text(' Some Text'),
Text(' label '),
]),
],
));
},
body: SingleChildScrollView(
child: ListView.builder(
itemCount: widgets.length,
itemBuilder: (context, index) => ListTile(title: widgets[index]),
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
)));
}).toList(),
);
}
Is it possible to scroll only list items and to keep header in fixed position?
You need to set height for your body and remove physics, shrinkWrap in order to get what you want, like this:
body: SizedBox(
height: 300,//<-- add this
child: ListView.builder(
itemCount: widgets.length,
itemBuilder: (context, index) =>
ListTile(title: widgets[index]),
scrollDirection: Axis.vertical,
),
),
I want to add a listview in Card widget. It works when scroll vertically, but not when scroll horizontally. How can I fix it? It is in Sizedbox. I tried flexible and expanded but doesnt work.
return Scaffold(
appBar: appBar(),
body: Padding(
padding: const EdgeInsets.only(top: 5, left: 8, right: 5),
child: Column(
children: [
Card(
elevation: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 100,
width: 110,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: TextButton(onPressed: () {}, child: Text(brandName[index])),
);
},),),)],),),],),),);
Do this instead:
/*...*/
SizedBox(
height: 100,
width: 110,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
width: // set a value,
child: ListTile(
// for suggestion you don't need `TextButton` here
// just do `title: Text(brandName[index])` and use the `onTap` function of `ListTile` instead
title: TextButton(
onPressed: () {},
child: Text(brandName[index])
)
),
);
},
),
)
/*...*/
Wrap your ListTile with SizedBox() and explicitly specify the width of ListTile.
eg. SizedBox (width: 100, LisTile(...))
For better understanding refer this answer.
I have a SliverToBoxAdapter containing a ListView of FilterChips. I want to add a title at the beginning of ListView but I'm always getting a Horizontal viewport was given unbounded width error.
Here's my code:
SliverToBoxAdapter(
child: Container(
height: 70,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: _expectedAnswers.length,
separatorBuilder: (context, index) {
return SizedBox(height: 7, width: 7);
},
itemBuilder: (context, index) {
return FilterChip(
label: Text('Hello');
// rest of FilterChip params here
);
},
),
),
);
This code as is works OK. But when I'm trying to add a title in front of the list, I'm getting the error above. Here's my attempt:
SliverToBoxAdapter(
child: Container(
height: 70,
child: Row(
children: <Widget>[
Text('Title'),
ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: _expectedAnswers.length,
separatorBuilder: (context, index) {
return SizedBox(height: 7, width: 7);
},
itemBuilder: (context, index) {
return FilterChip(
label: Text('Hello');
// rest of FilterChip params here
);
},
),
],
),
I created a card and set a width of container to 300 but i get the card with a width more than 300
return Card(
margin: EdgeInsets.symmetric(horizontal:5,vertical: 10),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
CourseInfoPage(widget.courseId)));
},
child: Container(
width: 300,
height: 200,
color:Colors.yellow,
child: Row(
children: <Widget>[
// courseText(context, course, 180),
// courseImage(course, 150),
Container(width: 100,color:Colors.red),
Container(width:200,color: Colors.green,)
],
),
),
),
);
and when i get it inside ListView like this
Container(
alignment: Alignment.center,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Selector<CategoriesModel, List<CourseModel>>(
selector: (buildContext, model) => model.getCoursesByCategory(categoryName),
builder: (context, value, child) => value == null
? CircularProgressIndicator()
: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: value.length,
itemBuilder: (BuildContext context, int index) {
return CourseCard(value[index].courseId);
},
),
),
),
I want the card to be exactly 300 and one container to 100 and an other to 200 which make it to be 300 but as you can see in the below screenshot i get this extra yellow space
the problem is in the Listview widget. Listview expands its children. To prevent this from happening, you need to wrap your CourseCard inside an Align widget and give it an alignment. check the following code. also, check this answer for more information.
ListView.builder(
scrollDirection: Axis.vertical,
itemCount: 2,
itemBuilder: (BuildContext context, int index) {
return Align(
alignment: Alignment.center,
child: CourseCard(value[index].courseId),
),
);
},
),
I wan´t to have a combination of text-widgets and lists inside a drawer. This content should be scrollable.
Here´s my sourcecode:
return Drawer(
child: Expanded(
child: Column(
children: <Widget>[
AppBar(title: Text('Test'),),
Text('Example 1:'),
ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _brands.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
....);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 5),
),
Text('Another heading')
],
),
),
);
What I want to achive:
The AppBar is fixed at the top
The other content below should be scrollable
I´ve tried different ways with Expanded, Columns etc. but I wasn´t able to get this layout up and running as expected. Thanks in advance for any input!
you can use a single column with the listview places inside an expanded widget
return Drawer(
child: Column(
children: <Widget>[
AppBar(),
Expanded(
child: ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: 100,
itemBuilder: (context, index) {
return Text(index.toString());
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 5),
),
),
],
),
);
yeilds
For short you can wrap your ListView with Expanded widget, it will fill all available space, but you will able to scroll it. In another case you should wrap ListView with Container and set height property.
For your example:
Drawer(
child: Column(
children: <Widget>[
AppBar(title: Text('Test'),),
Text('Example 1:'),
Expanded(
child: ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: List.generate(100, (index) => index).length,
itemBuilder: (BuildContext context, int index) {
return ListTile(leading: Text("$index"),);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 5),
),
),
Text('Another heading')
],
),
),