Rogerto
Rogerto

Reputation: 327

How to sort and display stream in Flutter from Firestore

I am returning a stream from Firestore. I want to sort results by date and display in Week 1, Week 2 etc.

However I only want to display Week 1, Week 2 etc. only once with the relevant number of sorted items displaying underneath. At the moment it displays for every item returned in stream and I do not want this.

It currently looks like this, but I do not want Week 2 to display multiple times only once:

enter image description here

class UserReflections extends StatefulWidget {
  final String? myString;

  const UserReflections({Key? key, this.myString}) : super(key: key);

  @override
  _UserReflectionsState createState() => _UserReflectionsState();
}

class _UserReflectionsState extends State<UserReflections> {
  late final Stream<QuerySnapshot> _usersStream;

  Color cardColor = Color(0xFFEDAF99);
  Color sage = Color(0xFF6f7c6b);
  Color rust = Color(0xFFF58500);
  Color lavendar = Color(0xFFC2AECD);
  Color backgroundColor = Color(0xFFF6F6F6);
  Color backgroundColorBlue = Color(0xFFE8EEF3);
  Color cardColorOne = Color(0xFFFFE3D3);
  Color cardColorTwo = Color(0xFFFFE8EC);
  Color cardColorThree = Color(0xFFFFFACA);
  Color cardColorFour = Color(0xFFEEE5FF);
  Color SliderColor = Color(0xFFEDAF99);
  Color purpleColor = Color(0xFFB84DEC);

  @override
  void initState() {
    _usersStream = FirebaseFirestore.instance
        .collection('reflection')
        .where("uid", isEqualTo: FirebaseAuth.instance.currentUser!.uid)
        .orderBy('dateTime', descending: true)
        .snapshots();
  }

  @override
  Widget build(BuildContext context) {
    final _user = Provider.of<UserListModel>(context).returnToDos;

    return StreamBuilder<QuerySnapshot>(
      stream: _usersStream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          print(snapshot.error);
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return SliverToBoxAdapter(
            child: Center(
              child: Text(
                "Loading",
                style: TextStyle(fontSize: 30, color: Colors.black),
              ),
            ),
          );
        }

        return SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, i) {
              DocumentSnapshot documentSnapshot = snapshot.data!.docs[i];

              final Timestamp timestamp = documentSnapshot['dateTime'];
              final DateTime date = timestamp.toDate();
              final dateFormatter = DateFormat('yyyy-MM-dd');
              final dateString = dateFormatter.format(date);
              final myFormatDateString = DateFormat.yMMMMEEEEd().format(date);
              final difference =
                  date.difference(_user[0].dateTime!.toDate()).inDays;

              return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    difference <= 7
                        ? Padding(
                            padding: EdgeInsets.only(
                                top: 10, bottom: 10, left: 20, right: 15),
                            child: Text('Week 1'),
                          )
                        : Padding(
                            padding: EdgeInsets.only(
                                top: 10, bottom: 10, left: 20, right: 15),
                            child: Text("Week 2")),

                    GestureDetector(
                      onTap: () {},
                      child: Padding(
                        padding: EdgeInsets.only(
                            top: 10, bottom: 10, left: 15, right: 15),
                        child: Container(
                          width: MediaQuery.of(context).size.width / 1.08,
                          decoration: BoxDecoration(
                            color: cardColorOne,
                            borderRadius: BorderRadius.circular(12),
                          ),
                          child: Padding(
                            padding: EdgeInsets.only(
                                left: 15, top: 15, right: 15, bottom: 15),
                            child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.spaceBetween,
                                      children: [
                                        Text(
                                          documentSnapshot['tag'],
                                          style: TextStyle(
                                              color: Colors.black,
                                              fontSize: 17,
                                              fontWeight: FontWeight.w600),
                                        ),
                                        Align(
                                          alignment: Alignment.centerRight,
                                          child: Padding(
                                              padding: EdgeInsets.only(
                                                  top: 2, bottom: 0, right: 5),
                                              child: Image.asset(
                                                  'assets/images/sitting.png',
                                                  height: 40,
                                                  width: 58,
                                                  fit: BoxFit.cover)),
                                        ),
                                      ]),
                                  SizedBox(height: 5),

                                  Text(
                                    myFormatDateString,
                                    style: TextStyle(
                                        color: Colors.black,
                                        fontSize: 13,
                                        fontWeight: FontWeight.w400),
                                  ),
                                  SizedBox(height: 10),
                                  Text(
                                    documentSnapshot['reflectionEntry'],
                                    style: TextStyle(
                                        color: Colors.black,
                                        fontSize: 17,
                                        fontWeight: FontWeight.normal),
                                    // maxLines: 3,
                                    // overflow: TextOverflow.ellipsis,
                                  ),
                                  SizedBox(
                                    height: 15,
                                  ),
                                  // Align(
                                  //   alignment: Alignment.centerRight,
                                  //   child: Padding(
                                  //       padding: EdgeInsets.only(top: 5, bottom: 5),
                                  //       child: Image.asset(
                                  //           'assets/images/sitting.png',
                                  //           height: 40,
                                  //           width: 58,
                                  //           fit: BoxFit.cover)),
                                  // ),
                                ]),
                          ),
                        ),
                      ),
                    ),
                  ]);
            },
            childCount: snapshot.data!.docs.length,
          ),
        );
      },
    );
  }
}

Upvotes: 0

Views: 301

Answers (1)

BJW
BJW

Reputation: 1095

Perhaps something you can try:

Use helper booleans to detect whether it is the first in week 1 (or week 2).

Where you define all the colors, also define 4 booleans.

bool firstWeekOne = false;
bool secondWeekOne = false;
bool firstWeekTwo = false;
bool secondWeekTwo = false;

after

final difference =
              date.difference(_user[0].dateTime!.toDate()).inDays;

add

if (difference <= 7) {
    if (firstWeekOne) {
        secondWeekOne = true;
    }
    else {
        firstWeekOne = true;
    }
}
else {
    if (firstWeekTwo) {
        secondWeekTwo = true;
    }
    else {
        firstWeekTwo = true;
    }
}

change

                difference <= 7
                    ? Padding(
                        padding: EdgeInsets.only(
                            top: 10, bottom: 10, left: 20, right: 15),
                        child: Text('Week 1'),
                      )
                    : Padding(
                        padding: EdgeInsets.only(
                            top: 10, bottom: 10, left: 20, right: 15),
                        child: Text("Week 2")),

into

                difference <= 7
                    ? !secondWeekOne ? Padding(
                        padding: EdgeInsets.only(
                            top: 10, bottom: 10, left: 20, right: 15),
                        child: Text('Week 1'),
                      ) : SizedBox.shrink()
                    : !secondWeekTwo ? Padding(
                        padding: EdgeInsets.only(
                            top: 10, bottom: 10, left: 20, right: 15),
                        child: Text("Week 2"),
                      ) : SizedBox.shrink(),

Upvotes: 1

Related Questions