dart – Flutter – assistance with complex widget layout


I’m designing a shopping app that pulls data from an e-commerce store API. I’ve created this layout for the store items: enter image description here

Each item is a Card with a Row as the main child, which contains the Image widget and two Columns for the text. The first column holds the title and subtitle, while the second one holds the price. It looks good now, but if the subtitle is any bigger, then this happens:

enter image description here

I’d ideally like the title and price to be grouped together, with the title aligned left and the price justified right, with the subtitle being able to take up the rest of the remaining width of the card.

I am familiar with how the Flutter layout works, but this task seems a bit beyond me. Even getting to this stage was a real challenge. I know that the parent’s height and width can be obtained with LayoutBuilder, but this sort of thing requires calculating sibling width (and possibly height), which I’m not sure how to do. So any help here would be good.

Here is the code for the widget:

import 'package:flutter/material.dart';

class ProductItem extends StatelessWidget {
  final String name;
  final String shortDescription;
  final double price;
  final String imageUrl;

  ProductItem({this.name, this.shortDescription, this.price, this.imageUrl});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: Card(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>(
            new Image.network(
              imageUrl,
              fit: BoxFit.fill,
              width: MediaQuery.of(context).size.width * 0.3,
            ),
            SizedBox(width: 15,),
            Column(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>(
                Text(
                  name,
                  textAlign: TextAlign.left,
                  style: new TextStyle(
                    fontSize: 20.0,
                    color: const Color(0xFF000000),
                    fontWeight: FontWeight.w600,
                  ),
                ),
                Text(
                  shortDescription,
                  textAlign: TextAlign.left,
                  style: new TextStyle(
                    fontSize: 16.0,
                    color: const Color(0xFF000000),
                    fontWeight: FontWeight.w200,
                  ),
                ),
              ),
            ),
            SizedBox(width: 20),

            Expanded(
              child: Row(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: (
                  Text(
                    '฿${price.toStringAsFixed(0)}',
                    textAlign: TextAlign.right,
                    style: new TextStyle(
                      fontSize: 20.0,
                      color: const Color(0xFF000000),
                      fontWeight: FontWeight.w500,
                    ),
                  )
                ),
              ),
            )
          ),
        ),
      ),
    );
  }
}