I tried to do the
Write Your First Flutter App, part 2 flutter app page 5
I now have a question for this application. I want to remove an entry from that List onLongPress like this:
onLongPress: () {
setState(() {
_saved.remove(pair);
});
},
This will remove the item from the list but won't update the screen. On returning to the home and reopening this route the new items without the deleted. But how can I trigger the update on this page without the user to reopen the page.
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Startup Name Generator',
home: RandomWords(),
theme: new ThemeData(
primaryColor: Colors.orange,
),
);
}
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final TextStyle _biggerFont = const TextStyle(fontSize: 18);
final Set<WordPair> _saved = new Set<WordPair>();
_buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
},
);
}
Widget _buildRow(WordPair pair) {
final bool alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(pair.asPascalCase, style: _biggerFont),
trailing: new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Startup Name Generator"),
actions: <Widget>[
new IconButton(icon: const Icon(Icons.list), onPressed: _pushSaved),
],
),
body: _buildSuggestions(),
);
}
void _pushSaved() {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) {
final Iterable<ListTile> tiles = _saved.map(
(WordPair pair) {
return new ListTile(
//this is the delete operation
onLongPress: () {
setState(() {
_saved.remove(pair);
});
},
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
},
);
final List<Widget> divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return new Scaffold(
appBar: new AppBar(
title: const Text('Saved Suggestions'),
),
body: new ListView(children: divided),
);
},
),
);
}
}
That's because you're creating a new MaterialPageRoute.
Try this:
onLongPress: () {
_saved.remove(pair);
Navigator.of(context).pop();
_pushSaved();
},
With this solution you'll still see the view change. If you want to prevent that, you'll need a new stateful page, and a bit of refactoring:
_saved
items global (only for this example)_pushSaved
methodonPressed
function that used to call the _pushSaved
functionDetailPage
instead of the _pushSaved
methodLike so:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
// create a global saved set
Set<WordPair> savedGlobal = new Set<WordPair>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Startup Name Generator',
home: new RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('Startup Name Generator'),
actions: <Widget>[
// change the onPressed function
new IconButton(icon: const Icon(Icons.list), onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage()
)
);
}),
],
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (BuildContext _context, int i) {
if (i.isOdd) {
return const Divider();
}
final int index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair) {
final bool alreadySaved = savedGlobal.contains(pair);
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
savedGlobal.remove(pair);
} else {
savedGlobal.add(pair);
}
});
},
);
}
}
// add a new stateful page
class DetailPage extends StatefulWidget {
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
Iterable<ListTile> tiles = savedGlobal.map((WordPair pair) {
return new ListTile(
onLongPress: () {
setState(() {
savedGlobal.remove(pair);
});
},
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
});
final List<Widget> divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return new Scaffold(
appBar: new AppBar(
title: const Text('Saved Suggestions'),
),
body: new ListView(children: divided),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With