Flutter - Detect content overflow and clip it
You shouldn't use ClipRect
for your goals. Please try to add clipBehavior
parameter with the value Clip.antiAlias
to your Stack
widget.
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."),
),
),
],
),
),
);
}
}
This solution just fixes a clipping.
How to get height of a Widget? gives answer how to check widget height and add Text with a message about overflow
For those who want a "height limiter" (a widget which limits the height of its children, and if the child wants to be too high, show some hint), here is my code snippet that you can copy-and-paste:
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,
),
),
);
}
}
And the MeasureSize
just comes from https://stackoverflow.com/a/60868972/4619958.
Result looks like the following (the green children overflow the blue parent) when child too high; When child is short enough, nothing special is shown.
Thanks @Aleksandr and @Dpedrinha for their answer!