There are a couple of new features we want to add to our Name Generator. These include saving our favorite names, changing the UI etc.
Getting Ready to Display Favorites
To save a favorite, we need to have a way to keep track of them. So in our state object, we’re going to add a new property called _saved
. This will make it look like the following
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _saved = <WordPair>{}; // NEW
final _biggerFont = TextStyle(fontSize: 18.0);
/* ... snip ...*/
}
Likewise, withing BuildRow, we’ll need to have a property to see if something is already saved. So we’re going to add a property to that class called alreadySaved
.
final alreadySaved = _saved.contains(pair);
The question then arises how do you want to showcase the words that you have saved. There are a couple of options, but one is to add an icon, and change that icon based upon what the user selects. Common examples of this would be a heart, start, or a thumbs up. Depending upon your design choice, you could choose to display nothing for items you’ve not selected/saved, or a hallow version and filled versions of the icon depending upon the choice.
Either way, you will need to add an icon child. This will go into _buildRow
as it is where we are building rows. It will go after the title, attribute, and instead of being part of a child, it will be part of a trailing attribute, which puts the icon at the far end of the row.
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
);
}
If you do a hot reload, you’ll see the hallow icons appear on the screen. Since I want no icon to appear if it isn’t selected, I’m gong to replace Icons.favorite_border
with null
. I didn’t want to do this first however, because it would be hard to tell if my code update worked since we haven’t put any interactivity on it yet.
Adding the Interactivity
As we’ve seeing with adding interactivity to Flutter project before, we will apply the onTap event. We will apply it to the whole row, so anywhere the user clicks, or taps, on the row, will toggle it’s saved/liked/favorited state.
We’ll use the following code applied after the trailing attribute.
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
As you see, there is a setState
function call being made to update the state of the widget. It checks to see if it is already saved, and if so, it removes the pair (of words) from the _saved list. Else it will add the pair (of words) to the list.
pair
, if you didn’t see it, is the parameter passed in to the _buildRow
method. _saved
is the state object. If it changes, it requires a redraw.
Changing the Default Theme
Changing your default theme is fairly simple in many ways.
In the MyApp
, you build a MaterialApp
. At this point the Widget has a title and a home which are set. Well, you can add a theme property to it.
The theme
property takes a datatype of ThemeData. When you create an object of ThemeData, you can pass in parameters to control it.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Name Generator',
theme: ThemeData(primaryColor: Colors.red),
home: RandomWords(),
);
}
}
Of course, there are other properties you can set at this point when you define your ThemeData. If you hover over the ThemeData class name, you can see a list of parameters you can set when you create it for your app.
Creating a Name Generator Part 2 was originally found on Access 2 Learn
One Comment
Comments are closed.