Mol0ko
Mol0ko

Reputation: 3298

Flutter: can I use different types of crossAxisAlignment inside one Row?

I have a ListView with dynamic height items. Each item is a Row with 3 elements: Text, Column, Column. ListView looks like this:

enter image description here

Here is the code of my item widget:

class ItemWidget extends StatelessWidget {
  final ItemViewModel model;

  const ItemWidget({Key key, @required this.model}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        SizedBox(width: 16),
        Text(
          model.typeLabel,
        ),
        SizedBox(width: 8),
        Expanded(
          flex: 6,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              SizedBox(height: 4),
              Text(
                'Volume:',
                textAlign: TextAlign.end,
              ),
              SizedBox(height: 2),
              Text(
                model.volume,
                textAlign: TextAlign.end,
              ),
              SizedBox(height: 4),
              Text(
                'Filled:',
                textAlign: TextAlign.end,
              ),
              SizedBox(height: 2),
              Text(
                model.filled,
                textAlign: TextAlign.end,
              ),
              SizedBox(height: 4)
            ],
          ),
        ),
        SizedBox(width: 16),
        Expanded(
            flex: 6,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                SizedBox(height: 4),
                Text(
                  'Price:',
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 2),
                Text(
                  model.price,
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 4),
                Text(
                  'Total:',
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 2),
                Text(
                  model.total,
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 4),
                Text(
                  'Fee:',
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 2),
                Text(
                  model.fee,
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 4),
              ],
            )),
        SizedBox(width: 16),
      ],
    );
  }
}

I want my Column widgets to always be top-aligned, as they are when crossAxisAlignment of Row is CrossAxisAlignment.start. At the same time Text should be centered, as it is now when crossAxisAlignment of Row is CrossAxisAlignment.center. Here is what I want:

enter image description here

How can I achieve this?

Thanks for any help.

Upvotes: 1

Views: 2062

Answers (4)

w461
w461

Reputation: 2698

Just found this question again - with me facing the problem...

One can also use the opposite widget (Row-> Column Column->Row) as a wrapper and specify `MainAxisAlignment.start' there.

Upvotes: 0

Mol0ko
Mol0ko

Reputation: 3298

The answer: Row widget can't use different crossAxisAlignment types for its children.

But I found another solution for my layout, with Stack widget in root. Here is working code:

class ItemWidget extends StatelessWidget {
  final ItemViewModel model;

  const ItemWidget({Key key, @required this.model}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(children: [
      Positioned.fill(
        child: Container(
          padding: EdgeInsets.only(left: 16),
          alignment: Alignment.centerLeft,
          child: Text(model.typeLabel),
        ),
      ),
      Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(width: 24),
          Expanded(
            flex: 6,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                SizedBox(height: 4),
                Text(
                  'Volume:',
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 2),
                Text(
                  model.volume,
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 4),
                Text(
                  'Filled:',
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 2),
                Text(
                  model.filled,
                  textAlign: TextAlign.end,
                ),
                SizedBox(height: 4)
              ],
            ),
          ),
          SizedBox(width: 16),
          Expanded(
              flex: 6,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  SizedBox(height: 4),
                  Text(
                    'Price:',
                    textAlign: TextAlign.end,
                  ),
                  SizedBox(height: 2),
                  Text(
                    model.price,
                    textAlign: TextAlign.end,
                  ),
                  SizedBox(height: 4),
                  Text(
                    'Total:',
                    textAlign: TextAlign.end,
                  ),
                  SizedBox(height: 2),
                  Text(
                    model.total,
                    textAlign: TextAlign.end,
                  ),
                  SizedBox(height: 4),
                  Text(
                    'Fee:',
                    textAlign: TextAlign.end,
                  ),
                  SizedBox(height: 2),
                  Text(
                    model.fee,
                    textAlign: TextAlign.end,
                  ),
                  SizedBox(height: 4),
                ],
              )),
          SizedBox(width: 16),
        ],
      )
    ]);
  }
}

The result is:

enter image description here

Upvotes: 1

rgisi
rgisi

Reputation: 952

Do I understand correctly: You have rows with 3 elements, and you want the first to be centered and other two to be top-aligned?

I think your main misunderstanding is that Columns don't automatically stretch to the whole height, and so their content may be top aligned, but they themselves are center-aligned within the row.

This is a very good guide on the topic, and it's very important to understand.

You can probably solve your immediate problem wrapping your middle element with an Align() widget.

Upvotes: 1

w461
w461

Reputation: 2698

not sure if this is possible. If the layout is as simple as shown, I would simply add some blank lines so that the mid and right column have the same length. Dirty workaround, but better than nothing ;-)

Upvotes: 0

Related Questions