Dimibe / grouped_list

A Flutter ListView in which items can be grouped into sections.
https://pub.dev/packages/grouped_list
MIT License
391 stars 107 forks source link

if there are more than 33 elements list order messed up #167

Open aju-annaseem opened 1 year ago

aju-annaseem commented 1 year ago

33 elements in list working fine WhatsApp Image 2022-11-21 at 10 36 25 AM

if more than 33 elements shuffling WhatsApp Image 2022-11-21 at 10 36 26 AM

aju-annaseem commented 1 year ago

my code as below: i want to show 1 to 34 numbers orderly.. pls help

import 'package:flutter/material.dart'; import 'package:grouped_list/grouped_list.dart'; import 'package:intl/intl.dart';

`void main() => runApp(const MyApp());

class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);

@override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const TestChat()); } }

class TestChat extends StatelessWidget { const TestChat({Key? key}) : super(key: key);

@override Widget build(BuildContext context) { List messageList = [ // Message( // msg: '40', // date: DateTime.now().subtract(Duration(days: 2, minutes: 6)), // isme: true, // ), // Message( // msg: '39', // date: DateTime.now().subtract(Duration(days: 2, minutes: 5)), // isme: false, // ), // Message( // msg: '38', // date: DateTime.now().subtract(Duration(days: 2, minutes: 4)), // isme: true, // ), // Message( // msg: '37', // date: DateTime.now().subtract(Duration(days: 2, minutes: 3)), // isme: false, // ), // Message( // msg: '36', // date: DateTime.now().subtract(Duration(days: 2, minutes: 2)), // isme: true, // ), // Message( // msg: '35', // date: DateTime.now().subtract(Duration(days: 2, minutes: 1)), // isme: false, // ), Message( msg: '34', date: DateTime.now().subtract(const Duration(days: 1, minutes: 58)), isme: true, ), Message( msg: '33', date: DateTime.now().subtract(const Duration(days: 1, minutes: 58)), isme: false, ), Message( msg: '32', date: DateTime.now().subtract(const Duration(days: 1, minutes: 57)), isme: true, ), Message( msg: '31', date: DateTime.now().subtract(const Duration(days: 1, minutes: 56)), isme: true, ), Message( msg: '30', date: DateTime.now().subtract(const Duration(days: 1, minutes: 54)), isme: true, ), Message( msg: '29', date: DateTime.now().subtract(const Duration(days: 1, minutes: 53)), isme: false, ), Message( msg: '28', date: DateTime.now().subtract(const Duration(days: 1, minutes: 52)), isme: true, ), Message( msg: '27', date: DateTime.now().subtract(const Duration(days: 1, minutes: 51)), isme: false, ), Message( msg: '26', date: DateTime.now().subtract(const Duration(days: 1, minutes: 50)), isme: true, ), Message( msg: '25', date: DateTime.now().subtract(const Duration(days: 1, minutes: 49)), isme: false, ), Message( msg: '24', date: DateTime.now().subtract(const Duration(days: 1, minutes: 48)), isme: true, ), Message( msg: '23', date: DateTime.now().subtract(const Duration(days: 1, minutes: 47)), isme: false, ), Message( msg: '22', date: DateTime.now().subtract(const Duration(days: 1, minutes: 46)), isme: true, ), Message( msg: '21', date: DateTime.now().subtract(const Duration(days: 1, minutes: 45)), isme: true, ), Message( msg: '20', date: DateTime.now().subtract(const Duration(days: 1, minutes: 44)), isme: true, ), Message( msg: '19', date: DateTime.now().subtract(const Duration(days: 1, minutes: 43)), isme: false, ), Message( msg: '18', date: DateTime.now().subtract(const Duration(days: 1, minutes: 42)), isme: true, ), Message( msg: '17', date: DateTime.now().subtract(const Duration(days: 1, minutes: 41)), isme: false, ), Message( msg: '16', date: DateTime.now().subtract(const Duration(days: 1, minutes: 40)), isme: true, ), Message( msg: '15', date: DateTime.now().subtract(const Duration(days: 1, minutes: 39)), isme: false, ), Message( msg: '14', date: DateTime.now().subtract(const Duration(days: 1, minutes: 38)), isme: true, ), Message( msg: '13', date: DateTime.now().subtract(const Duration(days: 1, minutes: 37)), isme: false, ), Message( msg: '12', date: DateTime.now().subtract(const Duration(days: 1, minutes: 36)), isme: true, ), Message( msg: '11', date: DateTime.now().subtract(const Duration(days: 1, minutes: 35)), isme: true, ), Message( msg: '10', date: DateTime.now().subtract(const Duration(days: 1, minutes: 33)), isme: true, ), Message( msg: '9', date: DateTime.now().subtract(const Duration(days: 1, minutes: 32)), isme: false, ), Message( msg: '8', date: DateTime.now().subtract(const Duration(days: 1, minutes: 31)), isme: true, ), Message( msg: '7', date: DateTime.now().subtract(const Duration(days: 1, minutes: 30)), isme: false, ), Message( msg: '6', date: DateTime.now().subtract(const Duration(days: 1, minutes: 29)), isme: true, ), Message( msg: '5', date: DateTime.now().subtract(const Duration(days: 1, minutes: 28)), isme: false, ), Message( msg: '4', date: DateTime.now().subtract(const Duration(days: 1, minutes: 27)), isme: true, ), Message( msg: '3', date: DateTime.now().subtract(const Duration(days: 1, minutes: 26)), isme: false, ), Message( msg: '2', date: DateTime.now().subtract(const Duration(days: 1, minutes: 25)), isme: true, ), Message( msg: '1', date: DateTime.now().subtract(const Duration(days: 1, minutes: 21)), isme: true, ), ]; return Scaffold( appBar: AppBar(title: const Text('Chat Screen')), body: GroupedListView<Message, DateTime>( reverse: true, elements: messageList.reversed.toList(), groupBy: (message) => DateTime( message.date.year, message.date.month, message.date.day, ), groupHeaderBuilder: (Message message) => SizedBox( height: 40, child: Center( child: Card( color: Colors.grey[200], child: Padding( padding: const EdgeInsets.all(5), child: Text( DateFormat.yMMMd().format(message.date), style: const TextStyle(), ), ), ), ), ),

    itemBuilder: (context, Message element) => GroupedMessageBubble(
      chatData: element,
    ),

    useStickyGroupSeparators: true, // optional
    floatingHeader: true, // optional
    order: GroupedListOrder.DESC, // optional
  ),
);

} }

class Message { final String msg; final DateTime date; final bool isme; final String? chatImage;

Message( {required this.msg, required this.date, required this.isme, this.chatImage}); }

class GroupedMessageBubble extends StatelessWidget { final Message chatData; const GroupedMessageBubble({Key? key, required this.chatData}) : super(key: key);

@override Widget build(BuildContext context) { return Align( alignment: chatData.isme ? Alignment.centerRight : Alignment.centerLeft, child: Column( crossAxisAlignment: chatData.isme ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ Container( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * 0.7), // alignment: Alignment.centerRight, margin: EdgeInsets.only( left: chatData.isme ? 80 : 20, right: chatData.isme ? 20 : 80, top: 10), padding: const EdgeInsets.symmetric( horizontal: 5, vertical: 5, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(7), color: chatData.isme ? Colors.green : const Color(0xFFF2F2F2)), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: Text( chatData.msg, style: chatData.isme ? const TextStyle( fontWeight: FontWeight.w400, fontSize: 14, color: Colors.white) : const TextStyle( color: Colors.grey, fontSize: 14, fontWeight: FontWeight.w400, ), ), )), Align( alignment: chatData.isme ? Alignment.centerRight : Alignment.centerLeft, child: Padding( padding: const EdgeInsets.only( left: 20, right: 20, top: 5, bottom: 10), child: Text( // DateFormat.Hm().format(DateTime.parse(chatData.date!)), '', style: TextStyle( color: Colors.grey[400], fontSize: 10, fontWeight: FontWeight.w500, ), ), ), ) ], ), ); } } `

bsolca commented 1 year ago

Hello @aju-annaseem, can you edit your message to have a better version to reproduce your code, so we can support your issue easier? (e.g.: dartpad.dev)

thefdisk commented 1 year ago

Same issue

prince-appiah commented 1 year ago

Same here, the order in which I have my sample data is not what it rendered in the list. Mine has just four elements. Any solution to this?

S0NN1 commented 11 months ago

I fixed it by disabling the sort parameter which, for some reason, is enabled by default. Since my list had custom types in it at some point (33rd message as other people), the sort algorithm broke. I will investigate more later on to see if I can find why such behavior exists.

Caffeinix commented 8 months ago

You can also fix this by specifying your own itemComparator. Otherwise, if your list item type doesn't implement Comparable, it claims to use the natural ordering of your source list, but actually what it does is calls sort on the list and returns null from the comparator for all elements, which is bad because sort isn't stable in the presence of elements that compare equal, which results in this weird behavior.

So, in rough order of preference, I would say the workarounds for this bug are:

  1. Specify itemComparator,
  2. Have your list item type implement Comparable and implement compareTo,
  3. Specify sort: false.

The code could be fixed by checking for this condition (no itemComparator, item type is not Comparable, and sort is true) and acting as though sort is false. I'd be happy to make a PR for this if someone can give me evidence that the package is still being maintained and my PR would be merged.

Dimibe commented 8 months ago

Hi @Caffeinix, I would appreciate if you can open a PR to fix this behavior. I am planning to release a new version shortly and this fix would be very helpful.

iksivee commented 3 months ago

Hello, can @Dimibe please perform a PR to fix this, as it does not seem to be done by @Caffeinix. I need to use sort for scrollController, to be able to navigate in list.