0

I want to implement the following design in Flutter, specifically the rounded rectangle with the Text placed on it. enter image description here

I have used the Stack widget to position the Text at the bottom left of the Container, but the problem is that the Text goes in one line beyond the Stack boundary, instead of breaking into the second line. For simplicity sake, I have written a simpler code as following:

@override 
Widget build(BuildContext context) {
return Center(
  child: Stack(
    children: [
      Container(
        width: 150,
        height: 150,
        color: Colors.teal.shade300,
      ),
      const Positioned(
        left: 16,
        bottom: 16,
        child: Text(
          "A very looooooooooooooooong teeeeeeeext",
          maxLines: 2,
          softWrap: true,
        ),
      ),
    ],
  ),
);
}

And the result is:

enter image description here

So how can I break the Text into the second line (not by using \n character), in this scenario. Or, if there is another solution other than using Stack, please tell me. Thanks.

2
  • Set Text.overflow .... Commented Jul 26, 2022 at 8:04
  • 1
    Add width to your Positioned widget to constrain Text width in order for it to know when to wrap. Commented Jul 26, 2022 at 8:07

6 Answers 6

2

You can use align inside the container instead of using stack

@override
Widget build(BuildContext context) {
return Center(
  child: Container(
    width: 150,
    height: 150,
    color: Colors.teal.shade300,
    child: const Align(
      alignment: Alignment.bottomLeft,
      child: Text(
        "A very looooooooooooooooong teeeeeeeext",
        maxLines: 2,
        softWrap: true,
      ),
    ),
  ),
);
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can use GridView to implement the following design. Like this:

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    mainAxisSpacing: 16.0,
    crossAxisSpacing: 16.0,
  ),
  children: [
    Container(
      width: 150,
      height: 150,
      color: Colors.teal.shade300,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('title1'),
          Text('21222222222222222222222222222')
        ],
      ),
    ),
    Container(
      width: 150,
      height: 150,
      color: Colors.teal.shade300,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('title1'),
          Text('21222222222222222222222222222')
        ],
      ),
    ),
    Container(
      width: 150,
      height: 150,
      color: Colors.teal.shade300,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('title1'),
          Text('21222222222222222222222222222')
        ],
      ),
    ),
    Container(
      width: 150,
      height: 150,
      color: Colors.teal.shade300,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('title1'),
          Text('21222222222222222222222222222')
        ],
      ),
    ),
  ],
)

Or you can use GridView.builder.

Comments

0

Use Expanded Widget

@override 
Widget build(BuildContext context) {
return Center(
  child: Stack(
    children: [
      Container(
        width: 150,
        height: 150,
        color: Colors.teal.shade300,
      ),
      const Positioned(
        left: 16,
        bottom: 16,
        child: Expanded(
             Text(
          "A very looooooooooooooooong teeeeeeeext",
          maxLines: 2,
          softWrapenter code here: true,
        ),
       ),
      ),
    ],
  ),
);
}

Comments

0

Use layout like this for multiple line text on stack.

Stack(

children: [

  CustomPaintCurves(),

  Positioned(

    top: 0.0,
    left: 0.0,
    right: 0.0,
    child: Column(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: Image.asset(
              AppAssets.icon_button_background,
              gaplessPlayback: true,
              fit: BoxFit.cover,
              height: 80,
              width: 80),
        ),
        const Padding(
          padding: EdgeInsets.all(8.0),
          child: Text(
            StringManager.appName,
            style: TextStyle(
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        const Padding(
          padding: EdgeInsets.all(8.0),
          child: Text(StringManager.aboutUsDescription),
        ),
      ],
    ),
  ),
],
),

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0

A sample code snippet

  Stack(
    children: [
      //! other children in this stack
      Positioned(
        left: 20, //! giving it random position
        bottom: 20,
        width: MediaQuery.of(context).size.width * 0.80, //! so that the `Text` widget knows where it overflows
        child: const Text(
          "Some Very Long Text Here .......", //! the long text you want to clip
          overflow: TextOverflow.ellipsis, //! type of overflow
          softWrap: false,
          maxLines: 3, //! max lines before clipping the text
        ),
      ),
    ],
  );

Explanation:

Gave random positions to the text widget (bottom left) of its container. Also gave width to the 'Positioned' widget so that the 'Text' widget knows where the text actually overflows and where it needs to apply the overflow properties.

I used 'TextOverflow.ellipsis' so that the overflowed text would go into the next line, but I specified how many lines of text I want to see (i.e. 'maxLines: 3') before the rest of the text is replaced with '...'.

Comments

0

this problem occur because inside stack you not applied any width of Text widget (child widget), so it will not take any width, so in your case wrap your text widget into SizeBox and applied width , it will work.

watch full code

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Stack(
          children: [
            Container(
              width: 150,
              height: 150,
              color: Colors.teal.shade300,
            ),
            const Positioned(
              left: 16,
              bottom: 16,
              child: SizedBox(
                width: 150,
           
                child: Text(
                  "A very looooooooooooooooong teeeeeeeext",
                  maxLines: 2,
                  softWrap: true,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


see the result enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.