Flutter: Make list scrollable - flutter

this is a typical question that might be considered as low quality but I have been on this for about two hours, and I am just trying to understand this piece of code better, so instead of just telling me how to fix, could you please also explain a bit what is happening. I am sure that for someone more experienced that me, should be very easy to spot.
I am trying to make a scrollable list, and draw each row of the list, and be able to click in each row item. But my app draws all the items but I am only able to see some of the items, as much as the screen allows, which means it is not scrollable.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some App Page'),
),
body: ListView(
children: <Widget>[
Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
TextField(
controller: cityController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: 'Enter city...'),
),
TextButton(
onPressed: () {
cityController.clear();
},
child: const Icon(Icons.clear),
),
],
),
ElevatedButton(
onPressed: () {
_futureTime = fetchTimes(int.parse(cityController.text));
if (cityController.text.isNotEmpty) {
setState(() {
cityController.clear(); // Clear value
}); // clear the textField
FocusScope.of(context)
.requestFocus(FocusNode()); // hide the keyboard
}
},
child: const Text('Get City', style: TextStyle(fontSize: 20)),
),
Column(
children: <Widget>[
Center(
child: FutureBuilder<Times>(
future: _futureTime,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const CircularProgressIndicator();
}
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return myTimeCard( date, index);
},
itemCount: data == null ? 0 : data.length,
);
},
),
),
],
),
],
),
);
}
Widget myTimeCard(String date, int index) {
return InkWell(
onTap: () {
// Navigate to the next page & pass data.
print("tapped, -> " + index.toString()); // for debugging purpose!
},
child: Stack(
children: <Widget>[
Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
index.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 22.0,
fontWeight: FontWeight.bold),
),
),
],
)
],
)
],
),
);
}

You are using two ListView s nested inside each other. In such cases you may need to let the Flutter know which ListView is the primary one. So, there is a property called primary. Try to set primary to false for the inner Listview.
return ListView.builder(
primary: false,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return myTimeCard( date, index);
},
itemCount: data == null ? 0 : data.length,
);

The code you shared does not compile because I do not have additional context, so I had to spend some time to be able to make it compile, please make sure to provide a compilable code in the future.
the problem you're facing is because the main ListView is taking control of the scroll, to see the effect try scrolling by holding the screen from the button Get City.
There are many ways to solve this problem, depending on your goal, do you want to make the whole screen scrollable, or just the data list
Way 1. Make the whole screen scrollable:
by keeping the control of the scroll in the main ListView, and making all the descending widgets non-scrollable, which in your case, by making the widget that wraps the data a Column instead of ListView:
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final TextEditingController cityController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some App Page'),
),
body: ListView(
children: <Widget>[
Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
TextField(
controller: cityController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: 'Enter city...'),
),
TextButton(
onPressed: () {
cityController.clear();
},
child: const Icon(Icons.clear),
),
],
),
ElevatedButton(
onPressed: () {
_futureTime = fetchTimes(int.parse(cityController.text));
if (cityController.text.isNotEmpty) {
setState(() {
cityController.clear(); // Clear value
}); // clear the textField
FocusScope.of(context)
.requestFocus(FocusNode()); // hide the keyboard
}
},
child: const Text('Get City', style: TextStyle(fontSize: 20)),
),
Column(
children: <Widget>[
Center(
child: FutureBuilder<Times>(
future: _futureTime,
builder: (context, snapshot) {
// if (!snapshot.hasData) {
// return const CircularProgressIndicator();
// }
final data =
// snapshot.data;
List.generate(50, (index) => index.toString());
return Column(
children: [
for (int i = 0; i < data.length; i++)
myTimeCard(data[i], i)
],
);
},
),
),
],
),
],
),
);
}
Widget myTimeCard(String date, int index) {
return InkWell(
onTap: () {
// Navigate to the next page & pass data.
print("tapped, -> " + index.toString()); // for debugging purpose!
},
child: Stack(
children: <Widget>[
Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
index.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 22.0,
fontWeight: FontWeight.bold),
),
),
],
)
],
)
],
),
);
}
}
Way 2. make the non-data widgets non-scrollable, and keep the scroll control in the data widget:
can be done by converting the main ListView to a non-scrollable Widget (in your case Column), and wrapping the data list in Expanded widget, so it takes all the space it can have (for more info about Expanded):
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final TextEditingController cityController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some App Page'),
),
body: Column(
children: <Widget>[
Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
TextField(
controller: cityController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: 'Enter city...'),
),
TextButton(
onPressed: () {
cityController.clear();
},
child: const Icon(Icons.clear),
),
],
),
ElevatedButton(
onPressed: () {
_futureTime = fetchTimes(int.parse(cityController.text));
if (cityController.text.isNotEmpty) {
setState(() {
cityController.clear(); // Clear value
}); // clear the textField
FocusScope.of(context)
.requestFocus(FocusNode()); // hide the keyboard
}
},
child: const Text('Get City', style: TextStyle(fontSize: 20)),
),
FutureBuilder<Times>(
future: _futureTime,
builder: (context, snapshot) {
// if (!snapshot.hasData) {
// return const CircularProgressIndicator();
// }
final data =
// snapshot.data;
List.generate(50, (index) => index.toString());
return Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return myTimeCard(date, index);
},
itemCount: data == null ? 0 : data.length,
),
);
},
),
],
),
);
}
Widget myTimeCard(String date, int index) {
return InkWell(
onTap: () {
// Navigate to the next page & pass data.
print("tapped, -> " + index.toString()); // for debugging purpose!
},
child: Stack(
children: <Widget>[
Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
index.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 22.0,
fontWeight: FontWeight.bold),
),
),
],
)
],
)
],
),
);
}
}

The issue is coming because we have two scrollable ListView. While both of them are scrollable, while scrolling when the inner ListView it gets focused and parent become unfocus and scroll event only effect on inner ListView and you can't rollback to parent ListView, A simple solution will be using NeverScrollableScrollPhysics on inner
ListView.builder.
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,

singleChildScrollView(
child: ListView.builder(
sinkwrap:true,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,)
)
Simple and Easy

Related

List view childs get out of container

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
),
)
])

Flutter: Keyboard causing a renderflex overflow error

I'm trying to display a message to the user unless there is a renderflex overflow error of 212px at the bottom. Actually, I use a separate widget to display the message, and every time I try to type with my phone, I get an error. I tried several solutions but none of them worked for me.
I would appreciate it if someone took a look. Thanks in advance!
Here is my code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
'Passation chat',
style: TextStyle(color: Colors.black),
),
centerTitle: true,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('Messages'),
Container(
height: 590,
child: SingleChildScrollView(
physics: ScrollPhysics(), reverse: true, child: ShowMessages()),
),
Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.blue, width: 0.2))),
child: TextField(
controller: msgController,
decoration: InputDecoration(hintText: 'Enter Message'),
),
),
),
IconButton(
onPressed: () {
if (msgController.text.isNotEmpty) {
storeMessage.collection('Messages').doc().set({
"msg": msgController.text.trim(),
"user": logInUser!.email.toString(),
"time": DateTime.now()
});
msgController.clear();
FocusManager.instance.primaryFocus?.unfocus();
}
},
icon: Icon(
Icons.send,
color: Colors.blueAccent,
))
],
),
],
),
);
}
}
class ShowMessages extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Messages')
.orderBy('time')
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
QueryDocumentSnapshot x = snapshot.data!.docs[index];
return ListTile(
title: Column(
crossAxisAlignment: logInUser!.email == x['user']
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: [
Container(
child: Column(children: [
Text(x['msg']),
SizedBox(
height: 5,
),
Text(
x['user'],
style: TextStyle(fontSize: 10),
)
]),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
decoration: BoxDecoration(
color: logInUser!.email == x['user']
? Colors.blue.withOpacity(0.2)
: Colors.amber.withOpacity(0.1),
borderRadius: BorderRadius.circular(15)),
),
],
),
);
},
shrinkWrap: true,
primary: true,
physics: ScrollPhysics(),
);
},
);
}
}
Screenshots from the app:
Make SingleChildScrollView the first widget of Scaffold body.
Fixed it by wrapping the Column widget by a SingleChildScrollView. Thanks mates!

A RenderFlex overflowed by 1443 pixels on the bottom

I am trying to make it scrollable...enter image description here For some reason its not not scrolling and i tried adding singleChildScrollview still not working.... Pls look at the picture to understand better... so i posted the full code so that you guys can help me better... This was the error i got "Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size. This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView."
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:memoryblog/helper/authenticate.dart';
import 'package:memoryblog/services/auth.dart';
import 'package:memoryblog/services/database.dart';
import 'package:memoryblog/views/create_blog.dart';
class MemoryRoom extends StatefulWidget {
#override
_MemoryRoomState createState() => _MemoryRoomState();
}
class _MemoryRoomState extends State<MemoryRoom> {
AuthMethod authMethod = new AuthMethod();
DatabaseMethods databaseMethod = new DatabaseMethods();
Stream blogsStream;
Widget BlogsList(){
return Container(
child: blogsStream != null ? Column(
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot){
if(snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index){
return BlogsTile(
authorName: snapshot.data.documents[index].data['memoryName'],
title: snapshot.data.documents[index].data['title'],
description: snapshot.data.documents[index].data['desc'],
imgUrl: snapshot.data.documents[index].data['imgUrl'],
);
}
);
},
)
],
) : Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
)
);
}
#override
void initState() {
// TODO: implement initState
databaseMethod.getData().then((result){
setState(() {
blogsStream = result;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Text(
"Memory"
),
Text(
"Blog",
style: TextStyle(
color: Colors.blue
),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
GestureDetector(
onTap: (){
authMethod.signOut();
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => Authenticate()
));
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.power_settings_new)),
)
],
),
body: BlogsList(),
floatingActionButton: Container(
padding: EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => CreateBlog()
));
},
child: Icon(Icons.add),
)
],
),
),
);
}
}
class BlogsTile extends StatelessWidget {
String imgUrl, title, description, authorName;
BlogsTile({#required this.imgUrl, #required this.title, #required this.description, #required this.authorName,});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16),
height: 170,
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: CachedNetworkImage(
imageUrl: imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
)
),
Container(
height: 170,
decoration: BoxDecoration(
color: Colors.black45.withOpacity(0.3),
borderRadius: BorderRadius.circular(6)
),
),
Container(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
SizedBox(height: 4,),
Text(
description,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
SizedBox(height: 4,),
Text(authorName)
],
),
)
],
),
);
}
}
Use ListView in place of the column. OR
Wrap Column with SingleChildScrollView
return Container(
child: blogsStream != null
? ListView(
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot) {
if (snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return BlogsTile(
authorName:
snapshot.data.documents[index].data['memoryName'],
title: snapshot.data.documents[index].data['title'],
description:
snapshot.data.documents[index].data['desc'],
imgUrl: snapshot.data.documents[index].data['imgUrl'],
);
});
},
)
],
)
: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);

How to add a grid to Cupertino Segmented Control in Flutter

I was referring to this link on Git Hub and I'm trying to add a grid to the segment.
My objective is to add images in a grid view to a segment in Cupertino Segmented Control
return Scaffold(
appBar: CupertinoNavigationBar(
middle: Text("awrdfsfsdfs"),
automaticallyImplyLeading: true,
transitionBetweenRoutes: true,
previousPageTitle: AppLocalizations.of(context).tr('alerts.back'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 20),
children: <Widget>[
CupertinoSegmentedControl(
children: {
0: Text(AppLocalizations.of(context).tr('titles.secImg')),
1: Text(AppLocalizations.of(context).tr('titles.secQuest')),
},
groupValue: _selectedIndexValue,
onValueChanged: (value) {
setState(() => _selectedIndexValue = value);
},
),
_selectedIndexValue == 0 ? IosFirstPage() : IosSecondPage()
],
),
)
],
),
);
}
}
class IosFirstPage extends StatelessWidget {
const IosFirstPage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
var imgList = [ ];
return Flex(
direction: Axis.vertical,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 10,left: 10),
child: Row(
children: <Widget>[
Text(AppLocalizations.of(context).tr('titles.selectSecImg'),style: textTheme.subtitle,textAlign: TextAlign.left,textScaleFactor: 1.2,),
],
)
),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: MediaQuery.of(context).size.height*0.64, //adjust this resize the scroll view of the images
margin: EdgeInsets.only(top: 10,left: 10,right: 10),
color: Colors.white30,
child: GridView.builder(
itemCount: imgList.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5),
itemBuilder: (BuildContext context, int index) {
return new GestureDetector(
child: new Card(
elevation: 1.0,
child: new Container(
alignment: Alignment.center,
margin: new EdgeInsets.only(
top: 10.0, bottom: 10.0),
child: new Image.asset(imgList[index], scale: 0.5,)
),
),
onTap: () {
print(index);
/*showDialog(
barrierDismissible: false,
context: context,
child: new CupertinoAlertDialog(
title: new Column(
children: <Widget>[
new Text("GridView"),
new Icon(
Icons.favorite,
color: Colors.red,
),
],
),
content: new Text( imgList[index]),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: new Text("OK"))
],
));*/
},
);
},
),
),
],
);
}
}
class IosSecondPage extends StatelessWidget {
const IosSecondPage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container();.
}
}

I want to delete selected data from the list using the delete button in action bar

I'm new to flutter and I want to delete the selected values from the
list,but I don't know how to delete selected Items,can anyone help?
I have taken icon button in Appbar and I tried to setState in it by
using the .removelast() command,but I want to select the Item then
delete it.
Code :
class DemoPage extends State<MyHomePage> {
TextEditingController Controller = TextEditingController();
List<String> msg = List();
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Demo_App'),
actions: <Widget>[
IconButton(icon: Icon(Icons.delete),
onPressed: (){
setState(() {
msg.removeLast();
});
}),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(right: 150.0,top: 10.0,left: 8.0),
child:TextField(
controller: Controller,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'please enter your name',
),
),
),
Container(
alignment: Alignment.topRight,
margin: EdgeInsets.only(left: 250.0,right: 10.0),
child: RaisedButton(
onPressed: () {
setState(() {
msg.add(Controller.text);
Controller.clear();
});
},
child: Text('Add'),
),
),
Expanded(
flex: 2,
child: Container(
child: Card(
margin: EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: msg.length,
itemBuilder: (context, index){
if(index.isInfinite){
return Divider();
}
return ListTile(
title: Text(msg[index]),
);
},),
),
)),
],
),
);
}
}
I want to select the data and then delete it using the icon Button in
the AppBar.
Lets assume you want to select your items by a single click.
Take a separate a list indexList and each time you select an item, you store the clicked index into indexList.
Then upon clicking delete button run a loop on indexList and remove items from your itemList using the stored indexes.
clean indexList
update your state
class DemoPage extends State<MyHomePage> {
TextEditingController Controller = TextEditingController();
List<String> msg = List();
List<int> selectedItems = List();
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Demo_App'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
msg.removeLast();
});
}),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(right: 150.0, top: 10.0, left: 8.0),
child: TextField(
controller: Controller,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'please enter your name',
),
),
),
Container(
alignment: Alignment.topRight,
margin: EdgeInsets.only(left: 250.0, right: 10.0),
child: RaisedButton(
onPressed: () {
setState(() {
msg.add(Controller.text);
Controller.clear();
});
},
child: Text('Add'),
),
),
Expanded(
flex: 2,
child: Container(
child: Card(
margin: EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: msg.length,
itemBuilder: (context, index) {
return new GestureDetector(
onLongPress: () {
if(selectedItems.contains(index))
selectedItems.remove(index);
else
selectedItems.add(index);
},
onTap: () {
if(selectedItems.contains(index))
selectedItems.remove(index);
else
selectedItems.add(index);
},
child: index.isInfinite
? Divider()
: ListTile(
title: Text(msg[index]),
));
}),
),
)),
],
),
);
}
void _deleteItems(){ // call _deleteItems() on clicking delete button
setState(() {
//set your state
for (final index in selectedItems)
msg.removeAt(index);
selectedItems.clear();
});
}
}