5

I'm trying to create an 'Event' widget that is made out of two text widgets arranged in a column. The width of the Event widget is determined by the first text widget (title). The second text (details) should be constrained by the title's width and wrap to the next line. Here's what I want: https://i.stack.imgur.com/0bbNr.png

I've tried this layout, but the Column's width is set to the detail text's width (largest child)

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    Text("Title"),
    Text("Some longer text that should wrap")
  ]
)
Tim Kozlov
  • 63
  • 4
  • Have you tried wrapping it with a container, like: https://stackoverflow.com/a/51931091/884522? – Jacob Phillips Oct 20 '19 at 04:19
  • I have, but if I don't set the container's width, it will expand to fit the detail text (instead of forcing it to wrap onto next line). In order to set the Container's width, I need to know how wide the title text will be at build. – Tim Kozlov Oct 20 '19 at 20:20
  • `final RenderBox box = context.findRenderObject();` then `box.size` might do what you need, but it's probably not the right way. – Jacob Phillips Oct 20 '19 at 23:37

3 Answers3

1

I was lucky to stumble into Container's width: double.minPositive:

Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          ListTile(
            title: Text('Membership'),
            subtitle: Text('Lorem / \$22 per month'),
          ),
          ListTile(
            title: Text('Start date'),
            subtitle: Text(DateFormat('MMM dd, yyyy').format(DateTime.now())),
          ),
          ListTile(
            title: Text('Card on file'),
            subtitle: Text('XXXX-1111'),
          ),
          Container(
            width: double.minPositive,
            child: ListTile(
              title: Text(
                'Receipt and copy of the membership agreement will be sent to customer\'s email upon purchase.',
                style: Theme.of(context).textTheme.bodySmall,
              ),
            ),
          ),
        ],
      ),

enter image description here

Anton Duzenko
  • 2,366
  • 1
  • 21
  • 26
0

So I know I'm late to this question. But I had the same problem with you. After searching around, I'm surprised no one has written a package about this yet.

So I did: https://pub.dev/packages/flex_with_main_child

It'll look something like this:

ColumnWithMainChild(
  mainAxisAlignment: MainAxisAlignment.start,
  mainChild: Text("Title"),
  childrenBelow: [
    Text("Some longer text that should wrap"),
  ]
)
Shuang Li
  • 75
  • 1
  • 9
0

Solution full code:

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey _globalKey = GlobalKey();
  double? titleWidth;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      RenderBox renderBox =
          _globalKey.currentContext?.findRenderObject() as RenderBox;
      setState(() {
        titleWidth = renderBox.size.width;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ConstrainedBox(
          constraints: titleWidth == null
              ? const BoxConstraints()
              : BoxConstraints(
                  maxWidth: titleWidth!,
                ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              Text(
                "Your Title Here",
                key: _globalKey,
                style: const TextStyle(color: Colors.red),
              ),
              const Text("Some longer text that should wrap")
            ],
          ),
        ),
      ),
    );
  }
}

Result:

enter image description here

聂超群
  • 1,659
  • 6
  • 14