Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the size of the Text Widget in flutter

Tags:

flutter

dart

I've painted a shape for the background of my content of Text.

I want the background autoscale the Text, even the softWrap being true.

So, I need to get the width and height of my Text Widget before Widget build(BuildContext context).

Actually, I am simulating the chat bubble effect like iOS message using flutter. Here is the iOS version tutorial. Creating a Chat Bubble .

The core code below:

let label =  UILabel()
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 18)
label.textColor = .white
label.text = text

let constraintRect = CGSize(width: 0.66 * view.frame.width,
                            height: .greatestFiniteMagnitude)
let boundingBox = text.boundingRect(with: constraintRect,
                                    options: .usesLineFragmentOrigin,
                                    attributes: [.font: label.font],
                                    context: nil)
label.frame.size = CGSize(width: ceil(boundingBox.width),
                          height: ceil(boundingBox.height))

let bubbleSize = CGSize(width: label.frame.width + 28,
                             height: label.frame.height + 20)

let width = bubbleSize.width
let height = bubbleSize.height

=========================================
SOLUTION
Here is my solution.

bubble.dart:

// Define a CustomPainter to paint the bubble background.
class BubblePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..color = Color(0xff188aff)
      ..style = PaintingStyle.fill;
    final Path bubble = Path()
      ..moveTo(size.width - 22.0, size.height)
      ..lineTo(17.0, size.height)
      ..cubicTo(
          7.61, size.height, 0.0, size.height - 7.61, 0.0, size.height - 17.0)
      ..lineTo(0.0, 17.0)
      ..cubicTo(0.0, 7.61, 7.61, 0.0, 17.0, 0.0)
      ..lineTo(size.width - 21, 0.0)
      ..cubicTo(size.width - 11.61, 0.0, size.width - 4.0, 7.61,
          size.width - 4.0, 17.0)
      ..lineTo(size.width - 4.0, size.height - 11.0)
      ..cubicTo(size.width - 4.0, size.height - 1.0, size.width, size.height,
          size.width, size.height)
      ..lineTo(size.width + 0.05, size.height - 0.01)
      ..cubicTo(size.width - 4.07, size.height + 0.43, size.width - 8.16,
          size.height - 1.06, size.width - 11.04, size.height - 4.04)
      ..cubicTo(size.width - 16.0, size.height, size.width - 19.0, size.height,
          size.width - 22.0, size.height)
      ..close();
    canvas.drawPath(bubble, paint);
  }

  @override
  bool shouldRepaint(BubblePainter oldPainter) => true;
}

// This is my custom RenderObject.
class BubbleMessage extends SingleChildRenderObjectWidget {
  BubbleMessage({
    Key key,
    this.painter,
    Widget child,
  }) : super(key: key, child: child);

  final CustomPainter painter;

  @override
  RenderCustomPaint createRenderObject(BuildContext context) {
    return RenderCustomPaint(
      painter: painter,
    );
  }

  @override
  void updateRenderObject(
      BuildContext context, RenderCustomPaint renderObject) {
    renderObject..painter = painter;
  }
}

Use the BubbleMessage Widget like this:

import 'bubble.dart' 

...code ... 

BubbleMessage(
  painter: BubblePainter(),
  child: Container(
    constraints: BoxConstraints(
      maxWidth: 250.0,
      minWidth: 50.0,
    ),
    padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 6.0),
    child: Text(
      'your text variable',
      softWrap: true,
      style: TextStyle(
        fontSize: 16.0,
      ),
    ),
  ),
),

...code ...

The bubble effect:

enter image description here

like image 365
Jianjian Yang Avatar asked Oct 05 '18 06:10

Jianjian Yang


People also ask

How do I get the widget size in Flutter?

First, you need to assign a GlobalKey to the widget. If you've assigned the GlobalKey to the widget, you can get the currentContext property of the key and call the findRenderObject() method. The result can be casted to RenderBox . You can get the size from the RenderBox 's size property.

How do you get the text length in Flutter?

To find length of a given string in Dart, you can use length property of String class. String. length returns an integer specifying the number of characters in the string or otherwise called length.

How do I change the size of the text widget in Flutter?

To change the TextField height by changing the Font Size: Step 1: Inside the TextField, Add the style parameter and assign the TextStyle(). Step 2: Inside the TextStyle(), Add the fontSize parameter and set the appropriate value. Step 3: Run the app.

Which widget in Flutter comes with a specified size?

SizedBox is a built-in widget in flutter SDK. It is a simple box with a specified size. It can be used to set size constraints to the child widget, put an empty SizedBox between the two widgets to get some space in between, or something else.

How to get the size of a specific widget in flutter?

In Flutter, you can easily get the size of a specific widget after it’s rendered. What you need to do is to give it a key, then using that key to access currentContext.size property, like this:

How to change the font size of text in text widget?

You can change the font size of text in a Text Widget using style property. Create a TextStyle object with fontSize and specify this object as style for Text Widget. A quick code snippet is shown below. Change the value for fontSize to change the font size of text in Text Widget.

How do I set the width of a textfield in flutter?

This article shows you how to set the width, height, and inner padding of a TextField widget in Flutter. You can set the width of a TextField exactly as you want by wrapping it inside a Container, a SizedBox, or a ContrainedBox widget.

How to auto-resize widgets According to the screen in flutter?

The different screen has different sizes, so the widget tree, you can auto-resize them according to the screen in Flutter. See the example below: First, you need to add auto_size_text widget in your project by adding the following lines in pubspec.yaml file. Now to import the package in your script:


3 Answers

My apologies. This is not a direct answer on the topic's question! But If someone needs to get the size of a Text widget — this method can help. It helped me in creation of custom menu widget.

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

  @override
  Widget build(BuildContext context) {
    final String text = "Text in one line";
    final TextStyle textStyle = TextStyle(
      fontSize: 30,
      color: Colors.white,
    );
    final Size txtSize = _textSize(text, textStyle);

    // This kind of use - meaningless. It's just an example.
    return Container(
      color: Colors.blueGrey,
      width: txtSize.width,
      height: txtSize.height,
      child: Text(
        text,
        style: textStyle,
        softWrap: false,
        overflow: TextOverflow.clip,
        maxLines: 1,
      ),
    );
  }

  // Here it is!
  Size _textSize(String text, TextStyle style) {
    final TextPainter textPainter = TextPainter(
        text: TextSpan(text: text, style: style), maxLines: 1, textDirection: TextDirection.ltr)
      ..layout(minWidth: 0, maxWidth: double.infinity);
    return textPainter.size;
  }
}
like image 83
Dmitry_Kovalov Avatar answered Oct 16 '22 14:10

Dmitry_Kovalov


Problem with other answers is that if you use Text widget to display your text and constraint it with measurements result without considering default font family and scale factor, then you will get wrong results because Text widget is using device's textScaleFactor by default and passing it to RichText widget inside of it. This is the correct code to measure text size:

final Size size = (TextPainter(
        text: TextSpan(text: text, style: textStyle),
        maxLines: 1,
        textScaleFactor: MediaQuery.of(context).textScaleFactor,
        textDirection: TextDirection.ltr)
      ..layout())
    .size;
like image 53
Amir_P Avatar answered Oct 16 '22 14:10

Amir_P


I found another method without using the context:

final constraints = BoxConstraints(
  maxWidth: 800.0, // maxwidth calculated
  minHeight: 0.0,
  minWidth: 0.0,
);

RenderParagraph renderParagraph = RenderParagraph(
  TextSpan(
    text: text,
    style: TextStyle(
      fontSize: fontSize,
    ),
  ),
  textDirection: ui.TextDirection.ltr,
  maxLines: 1,
);
renderParagraph.layout(constraints);
double textlen = renderParagraph.getMinIntrinsicWidth(fontSize).ceilToDouble();
like image 29
mikes Avatar answered Oct 16 '22 13:10

mikes