Home > Enterprise >  Flutter How to get size of dynamic widget
Flutter How to get size of dynamic widget

Time:04-15

What I've done: enter image description here

The black rectangle is the size of the canvas.

const double radius = 50;


class TableShape extends StatelessWidget {
  final String name;
  final Color color;

  const TableShape({
    Key? key,
    required this.name,
    required this.color,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap:(){debugPrint("ok");},
        child: LayoutBuilder(
          builder: (context, constraints) {
            final maxWidth = constraints.maxWidth;
            final textPainter = TextPainter(
                text: TextSpan(
                  text: name,
                  style: const TextStyle(fontFamily: 'Graphik', fontSize: 30, color: Colors.white),
                ),
                textDirection: TextDirection.ltr,
                textAlign: TextAlign.center
            );
            textPainter.layout(maxWidth: maxWidth);
            return CustomPaint(
              size: Size(textPainter.width>radius*2?textPainter.width:radius*2, radius*2),
              painter: MyPainter(color: color, txt: textPainter),
            );
            })
    );
  }
}

class MyPainter extends CustomPainter {
  TextPainter txt;
  Color color;

  MyPainter({
    required this.txt,
    required this.color,
  });

  @override
  void paint(Canvas canvas, Size size) {
    canvas.clipRect(Rect.fromLTWH(0, 0, size.width, size.height));
    var paint = Paint()..color = color;
    bool txtLarger = txt.width>radius*2;

    canvas.drawCircle(Offset(txtLarger?txt.width/2:radius,radius), radius, paint);

    //table name:

    txt.paint(canvas, Offset(txtLarger?0:radius-txt.width/2,radius-txt.height/2));

  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }

  @override
  bool hitTest(Offset position) {
    return sqrt(pow(txt.width/2-position.dx,2) pow(radius-position.dy,2)) <= radius;
  }

}

I need to get the width because I place the widget on my screen according to its width. The width is dynamic: the bigger the text, the wider the canvas. Is it possible ? Or maybe you have an other approach to get this widget than the way I did ?

CodePudding user response:

get widget size by global key:

  final GlobalKey _widgetKey = GlobalKey();

  Size _getSize(GlobalKey key){
    final State state = key.currentState;
    final BuildContext context = key.currentContext;

    final RenderBox box = state.context.findRenderObject();
    return context.size;
  }

  Widget build(BuildContext context) {
    return GestureDetector(
        key: _widgetKey,
        onTap:(){_getSize(_widgetKey);},
        child: LayoutBuilder(
          builder: (context, constraints) {

CodePudding user response:

Use GlobalKey to find RenderBox then get the size. Remember you need to make sure the widget was rendered.

Example:

import 'package:flutter/material.dart';

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) => const MaterialApp(home: Home());
}

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);
  @override
  HomeState createState() => HomeState();
}

class HomeState extends State<Home> {
  var key = GlobalKey();
  Size? redboxSize;

  @override
  void initState() {
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      setState(() {
        redboxSize = getRedBoxSize(key.currentContext!);
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Example')),
      body: Column(
        children: [
          SizedBox(
            height: 100,
            child: Center(
              child: Container(
                key: key,
                child: const Text('Hello oooooooooooooooo'),
                color: Colors.redAccent,
              ),
            ),
          ),
          if (redboxSize != null) Text('Redbox size: $redboxSize')
        ],
      ),
    );
  }

  Size getRedBoxSize(BuildContext context) {
    final box = context.findRenderObject() as RenderBox;
    return box.size;
  }
}

enter image description here

CodePudding user response:

While the Text widget size is depending on text width itself, you are more like want to measure the text width.

You can check question on

I am copying this answer, pass your text and style and use the return width for your use case.

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;
}
  • Related