0

Row

I build a row of date with ListView.builder, each listview is a column with Day and Date. I want it to space evenly in the Row, but mainAxisAlignment: MainAxisAlignment.spaceEvenly seems only centred the listview :/

Another question is why do I need to wrap the listview builder with a fixed height? It worked but I don't think this is the best approach.

Thanks everyone in advance.

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

class TimeSlot extends StatefulWidget {
  @override
  _TimeSlotState createState() => _TimeSlotState();
}

class _TimeSlotState extends State<TimeSlot> {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        Container(
          height: 55,
          child: ListView.builder(
              scrollDirection: Axis.horizontal,
              shrinkWrap: true,
              itemCount: 8,
              itemBuilder: (context, i) {
                final weekDay = DateTime.now().add(
                  Duration(days: i),
                );
                final day = DateFormat.E().format(weekDay).substring(0, 2);
                final date = DateFormat.d().format(weekDay);
                return Column(
                  children: <Widget>[
                    Text(
                      day,
                      style: TextStyle(
                        color: Color.fromRGBO(30, 41, 51, 0.5),
                      ),
                    ),
                    SizedBox(
                      height: 7,
                    ),
                    CircleAvatar(
                      backgroundColor: Color.fromRGBO(240, 242, 245, 1),
                      radius: 14,
                      child: CircleAvatar(
                        backgroundColor: Colors.white,
                        child: Text(
                          date,
                          style: TextStyle(color: Colors.black, fontSize: 12),
                        ),
                        radius: 13,
                      ),
                    ),
                  ],
                );
              }),
        ),
      ],
    );
  }
}
Ennis
  • 67
  • 8

1 Answers1

0

Row checks all the children inside and then with the mainAxisAlignment.SpaceEvenly property it gives the correct space between them, the problem is that Row only detects one child inside, ListView.Builder (well the container wrapping the listview), even if the Listview has X amount of children, row only know he has one listview so it doesn't do anything. You either use row or listview.builder. This is an example using only Row and building the children inside with a for (and because they are in the children list of the row, now row can detect them and apply the correct mainAxisAlignment)

class TimeSlot extends StatefulWidget {
  @override
  _TimeSlotState createState() => _TimeSlotState();
}

class _TimeSlotState extends State<TimeSlot> {

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        for(int i = 0; i <= 8; i++)
        SingleDate(DateTime.now().add(Duration(days: i)))
      ],
    );
  }
}

class SingleDate extends StatelessWidget{
   final DateTime weekDay;

   SingleDate(this.weekDay);

   @override
   Widget build(BuildContext context){
     final day = MaterialLocalizations.of(context)
                .formatMediumDate(weekDay)
                .substring(
                    0,
                    MaterialLocalizations.of(context)
                        .formatMediumDate(weekDay)
                        .indexOf(','));
            return Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Text(
                  day,
                  style: TextStyle(
                    color: Color.fromRGBO(30, 41, 51, 0.5),
                  ),
                ),
                SizedBox(
                  height: 7,
                ),
                CircleAvatar(
                  backgroundColor: Color.fromRGBO(240, 242, 245, 1),
                  radius: 14,
                  child: CircleAvatar(
                    backgroundColor: Colors.white,
                    child: Text(
                      weekDay.day.toString(),
                      style: TextStyle(color: Colors.black, fontSize: 12),
                    ),
                    radius: 13,
                  ),
                ),
              ],
            );
   }

}
EdwynZN
  • 4,895
  • 2
  • 12
  • 15
  • I updated my answer just to comply with the Flutter guidelines of using classes instead of methods to return widgets, you can see a more specific example of why it's better to use classes here https://stackoverflow.com/questions/53234825/what-is-the-difference-between-functions-and-classes-to-create-reusable-widgets – EdwynZN May 31 '20 at 03:14
  • Thank you very much! – Ennis May 31 '20 at 22:26