Help us understand the problem. What is going on with this article?

【Flutter】Text Widgetのwidthを取得し、アニメーション付きでアンダーラインを表示する方法

アニメーション付きアンダーラインはAnimatedContainerで表現する。
Text Widgetのwidth取得方法はこちらを参考に実装。

header_menu_item.dart
class HeaderMenuItem extends StatefulWidget {
  final String text;
  final double fontSize = 16;

  const HeaderMenuItem({Key key, this.text}) : super(key: key);

  @override
  _HeaderMenuItemState createState() => _HeaderMenuItemState();
}

class _HeaderMenuItemState extends State<HeaderMenuItem> {
  double _opacity = 0;
  double _lineRatio = 0.5;

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (details) => _onEnterHandler(details, context),
      onExit: (details) => _onExitHandler(details, context),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 30.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Expanded(
              child: Container(
                alignment: Alignment.center,
                child: Text(
                  widget.text,
                  style: TextStyle(
                    fontSize: widget.fontSize,
                    letterSpacing: 5,
                  ),
                ),
              ),
            ),
            AnimatedContainer(
              width: lineWidth(widget.text) * _lineRatio,
              height: 2,
              color: Colors.black.withOpacity(_opacity),
              curve: Curves.linear,
              duration: Duration(milliseconds: 200),
            ),
          ],
        ),
      ),
    );
  }

  // マウスホバー時
  void _onEnterHandler(PointerEvent details, BuildContext context) {
    setState(() {
      _lineRatio = 1;
      _opacity = 1;
    });
  }

  // マウスホバー解除時
  void _onExitHandler(PointerEvent details, BuildContext context) {
    setState(() {
      _lineRatio = 0.5;
      _opacity = 0;
    });
  }

  // TextWidgetのwidthを取得
  double lineWidth(String text) {
    var renderParagraph = RenderParagraph(
      TextSpan(
        text: text,
        style: TextStyle(
          fontSize: widget.fontSize,
          letterSpacing: 5,
        ),
      ),
      textDirection: TextDirection.ltr,
    )..layout(BoxConstraints(maxWidth: 200));

    return renderParagraph.getMinIntrinsicWidth(widget.fontSize);
  }
}

参考

https://stackoverflow.com/questions/52659759/how-can-i-get-the-size-of-the-text-widget-in-flutter

kedev01
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away