【问题标题】:Flutter - Detect content overflow and clip itFlutter - 检测内容溢出并剪辑它
【发布时间】:2019-08-01 04:15:09
【问题描述】:

我正在尝试使用 ClipRect 并在其中使用 Column,但它似乎效果不佳。

我想要实现的是剪辑列的内容并在溢出时显示一条文本消息(如果列的内容无法在可用空间内显示)。

你有什么建议可以让我实现它吗?

import 'package:flutter/material.dart';

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

class ContentOverflowDetectionApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Overflow detection"),
        ),
        body: Stack(
          fit: StackFit.expand,
          children: [
            ClipRect(
              child: Column(
                children: [
                  Container(
                    width: 300,
                    height: 400,
                    color: Colors.green[200],
                    child: Text('first widget'),
                  ),
                  Container(
                    width: 350,
                    height: 350,
                    color: Colors.yellow[200],
                    child: Text('overflowed widget'),
                  ),
                ],
              ),
            ),
            Positioned(
              child: Align(
                alignment: FractionalOffset.bottomCenter,
                child: Text("SHOW THIS TEXT ONLY IF CONTENT HAS OVERFLOWED."),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

  • 您可以使用“SingleChildScrollView”而不是“列”
  • 恐怕我不需要滚动。此外,如果示例中的“Column”考虑到它支持子而不是子列,那么我不太明白如何使用“SingleChildScrollView”代替。

标签: dart flutter


【解决方案1】:

您不应该使用ClipRect 来实现您的目标。请尝试将值为Clip.antiAliasclipBehavior 参数添加到您的Stack 小部件。

import 'package:flutter/material.dart';

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

class ContentOverflowDetectionApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Overflow detection"),
        ),
        body: Stack(
          fit: StackFit.expand,
          clipBehavior: Clip.antiAlias,
          children: [
            Positioned(
              top: 0,
              child: Column(
                children: [
                  Container(
                    width: 300,
                    height: 400,
                    color: Colors.green[200],
                    child: Text('first widget'),
                  ),
                  Container(
                    width: 350,
                    height: 350,
                    color: Colors.yellow[200],
                    child: Text('overflowed widget'),
                  ),
                ],
              ),
            ),
            Positioned(
              child: Align(
                alignment: FractionalOffset.bottomCenter,
                child: Text("SHOW THIS TEXT ONLY IF CONTENT HAS OVERFLOWED."),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

这个解决方案只是修复了一个剪辑。

How to get height of a Widget? 给出了如何检查小部件高度并添加带有溢出消息的文本的答案

【讨论】:

  • 实际上,不是 clipBehaviour 而是 Positioned 小部件在这里起到了作用
【解决方案2】:

对于那些想要一个“高度限制器”(一个限制其孩子高度的小部件,如果孩子想要太高,请显示一些提示)的人,这是我的代码 sn-p 你可以复制 -并粘贴:

class HeightLimiter extends StatefulWidget {
  final Widget child;
  final double maxHeight;
  final double fadeEffectHeight;

  const HeightLimiter({Key key, this.maxHeight, this.child, this.fadeEffectHeight = 72}) : super(key: key);

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

class _HeightLimiterState extends State<HeightLimiter> {
  var _size = Size.zero;

  @override
  Widget build(BuildContext context) {
    return ConstrainedBox(
      constraints: BoxConstraints(
        maxHeight: widget.maxHeight,
      ),
      child: Stack(
        clipBehavior: Clip.hardEdge,
        children: [
          Positioned(
            top: 0,
            left: 0,
            right: 0,
            child: MeasureSize(
              onChange: (size) => setState(() => _size = size),
              child: widget.child,
            ),
          ),
          if (_size.height >= widget.maxHeight)
            Positioned(
              bottom: 0,
              left: 0,
              width: _size.width,
              child: _buildOverflowIndicator(),
            ),
        ],
      ),
    );
  }

  Widget _buildOverflowIndicator() {
    return Container(
      height: widget.fadeEffectHeight,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
          colors: [
            Colors.white.withAlpha(200),
            Colors.white.withAlpha(0),
          ],
          tileMode: TileMode.clamp,
        ),
      ),
    );
  }
}

MeasureSize 只是来自https://stackoverflow.com/a/60868972/4619958

当子级太高时,结果如下所示(绿色子级溢出蓝色父级);当孩子足够矮时,没有什么特别的表现。

感谢@Aleksandr 和@Dpedrinha 的回答!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-14
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 2017-06-28
    • 2021-11-30
    • 2019-06-07
    • 1970-01-01
    相关资源
    最近更新 更多