Home > other >  Flutter Grouped ListView: How to sort by Date?
Flutter Grouped ListView: How to sort by Date?

Time:08-31

I have a recipe app. Users can save recipes in a weekly planner (using Hive). The date is saved in this format: 2022-09-08 00:00:00.000 (= user wants to cook a recipe on September 8th).

On my planner page I want to display the scheduled recipes. I am using Grouped Listview for that to group my recipes by date. I also need to be able to sort the listed recipes (the recipe a user wants to cook tomorrow should be on top of the list and after that comes the day after tomorrow and so on). When I use the date in the format 2022-09-08 00:00:00.000 I am able to group the recipes and bring them in the correct order. But I don't like the format. I rather want to display (Thursday, 8. September). So I tried the following:

return Column(
        children: [
         SizedBox(height: 24),
          Expanded(
            child: GroupedListView<dynamic,String>(
              elements: jsonList,
               groupBy: (element) {
                element['plannerdate'];
                String date = DateFormat('dd. MMMM, EEEE').format(element['plannerdate']);
                return date;
              },
              groupSeparatorBuilder: (value) => Container(
                
                width: double.infinity,
                padding: const EdgeInsets.all(16),
                color: Colors.white,
                child: Text(value),
              ),
              itemBuilder: (context, element) => Card(
                child: Row(
         children: <Widget>[
            CircleAvatar(
              radius: 70,
              backgroundImage: NetworkImage(element['url'],
              ), 
           ),
         

But with that my date gets converted to a string. The format looks nice, but this way the order is messed up. Recipes from 31 August are at the end of the list while recipes from 2 September are on top. Can someone help?

Edit: My recipe class is:

//Recipe Model class for Hive Recipes Favorite Box


import 'package:hive/hive.dart';
part 'recipe_data_model.g.dart';

@HiveType(typeId: 0)
class RecipeModelData extends HiveObject {
  @HiveField(0)
   String? id;

  @HiveField(1)
   String? title;

  @HiveField(2)
   String? url;

  @HiveField(3)
   String? price;

  @HiveField(4)
   int? servings;

  @HiveField(5)
   String? calories;

  @HiveField(6)
   String? carbs;

  @HiveField(7)
   String? protein;

  @HiveField(8)
   String? fat;

  @HiveField(9)
   List? ingredients;

  @HiveField(10)
   List? instructions;

  @HiveField(11)
   DateTime? plannerdate;

  

 Map<String, dynamic> toJson() => 
  {
    'id': id,
    'title': title,
    'url': url,
    'price': price,
    'servings': servings,
    'calories': calories,
    'carbs': carbs,
    'protein': protein,
    'fat': fat,
    'ingredients': ingredients,
    'instructions': instructions,
    'plannerdate': plannerdate,
  };
}

And the jsonList with all the recipe details is:

flutter: jsonList: [{id: 1, title: Bananenbrott, url: https://firebasestorage.xyz, price: 0,77, servings: 1, calories: 234, carbs: 12, protein: 34, fat: 1, ingredients: [2 Bananen, 30 g Mehl, 2 Eier], instructions: [1. Zunächst das Ei mit den zerdrückten Bananen in einer Schüssel vermischen., 2. Dann das Mehl sieben und hinzufügen., 3. Alles umrühren und fertig], plannerdate: 2022-08-31 00:00:00.000}, {id: 2, title: Gemüsecurry, url: https://firebasestorage.xys, price: 1,20, servings: 1, calories: 450, carbs: 42, protein: 22, fat: 9, ingredients: [2 Dosen Kokosmilch, 400 ml Wasser, 1 Karotte], instructions: [1. Das Wasser zum Kochen bringen und dann mit der Kokosmilch vermischen., 2. Die Karotte schälen und dann mit dazu geben, 3. Alles miteinander gut kochen und verspeisen.]<…>

CodePudding user response:

You could display the formatted date in the groupSeparatorBuilder instead of in groupBy.

Example

return Column(
    children: [
     SizedBox(height: 24),
      Expanded(
        child: GroupedListView<dynamic,DateTime>(
          elements: jsonList,
           groupBy: (element) => element['plannerdate'],
          groupSeparatorBuilder: (value) { 
             String date = DateFormat('dd. MMMM, EEEE').format(value);
             Container(
               width: double.infinity,
               padding: const EdgeInsets.all(16),
               color: Colors.white,
               child: Text(date),
            )},
          itemBuilder: (context, element) => Card(
            child: Row(
     children: <Widget>[
        CircleAvatar(
          radius: 70,
          backgroundImage: NetworkImage(element['url'],
          ), 
       ),
  • Related