简体   繁体   中英

Using Dart / Flutter, How do I add favorites inside a ListViewBuilder?

I'm trying to allow a user to mark an item being built by a ListViewBuilder as a favorite. With my current code, when a user favorites one episode, all episodes are marked as favorite. I would like the user to be able to add each episode individually as a favorite and persist that favorite after a restart. I have the data saved to a firebase database but it seems like this should be handled in the app itself.

What is the best way to do this? Thanks!

Here is my current code:

class Epi {
  final String endTime;
  final String name;
  final String networkName;
  final String showName;
  final String startTime;

  Epi({this.endTime, this.name, this.networkName, this.showName, this.startTime});

  factory Epi.fromJson(Map<dynamic, dynamic> parsedJson) {
    DateTime endTimeCon = DateTime.parse(parsedJson['endTime']);
    String newEndTime = formatDate(endTimeCon, [yyyy, '/', mm, '/', dd, ' ', hh, ':', nn, ':', ss, ' ', am]);

    DateTime startTimeCon = DateTime.parse(parsedJson['startTime']);
    String newStartTime = formatDate(startTimeCon, [yyyy, '/', mm, '/', dd, ' ', hh, ':', nn, ':', ss, ' ', am]);

    return Epi(
      endTime: newEndTime,
      name: parsedJson['name'],
      networkName: parsedJson['networkName'],
      showName: parsedJson['showName'],
      startTime: newStartTime,
    );
  }
}
  bool _isFavorited = true;
  void _toggleFavorite() {
    setState(() {
      if (_isFavorited) {
        _isFavorited = false;
      } else {
        _isFavorited = true;
      }
    });
  }
body: Column(
          children: <Widget>[
            SizedBox(height: 5.0),
            Expanded(
              child: ListView.builder(
                  itemCount: elist.length,
                  itemBuilder: (context, index) {
                    return InkWell(
                      onTap: () {
                        selectEpisode(index);
                      },
                      child: Card(
                        child: Column(
                          children: <Widget>[
                          ListTile(
                            title: Text(elist[index].name),
                            subtitle: Text(elist[index].startTime),
                            leading: IconButton(
                              icon: (_isFavorited ? Icon(Icons.favorite_border) : Icon(Icons.favorite)),
                              color: Colors.red[500],
                              onPressed: _toggleFavorite,
                            ),
                            trailing: Icon(Icons.arrow_forward_ios)
                          )
                          ],
                        ),
                      ),
                    );
                  }),
            ),
          ],
        )

In my Congress Fahrplan App ( Github ) I'm doing exactly what you want to achieve.

In favorite_provider I store the value in the object itself and add it to my list of favorited objects . Whenever an object is added to this list, the list is written to the disk as JSON with my file_storage class.

When the app is restarted, the objects are fetched from a REST API. Then I match their IDs with the objects from the local JSON and set whether they are favorited or not to restore the favorite state.

Making a favorite list of items basically differs based on the app design and you might as well develop your own logic for this purpose. Now, while what @benjaminschilling33 posted is true, you can also achieve this in a simple way. What I would do is, add a boolean called isFavorite on the constructor like this:

 class Epi {
  final String endTime;
  final String name;
  final String networkName;
  final String showName;
  final String startTime;
  bool isFavorite;
}
//initialize the isFavorite to false cause no item in your list is is favorite at the beginning
Epi({this.endTime, this.name, this.networkName, this.showName, this.startTime, this.isFavorite=false});

//lets create a list _episode which contains all the movie for demonstration purpose
List<Epi> _episode = [Epi(initialized data)]; 
//create a getter for the list
List<Epi> get episode{
  return _episode.where((Epi episode) => episod.isFavorite).toList(); //this will return a list where the isFavorite is true
}

//You can then set your icon (in the list-tile) based on your isFavorite result
ListTile(
...
icon: Icons(elist[index].isFavorite?Icon(Icons.favorite):Icon(Icons.favorite_border);
)
//Then adjust the logic on your onPress
onPressed: (){
   setState((){
    elist[index].isFavorite=!elist[index].isFavorite //this will vary from true to false and vice versa when pressed
});
}

This is the simplest way to add list of items that is favorited by the user rather than building another list for the favorite section. What I wrote here is offline based test you can achieve and the key take away is the where property which is:

    List<Epi> episode=[some data]
    epsode.where((Epi episode)=>episode.isFavorite).toList();

You can use this method even after deploying your app to the cloud database by creating that attribute in your database based on the user's id.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM