I'm trying to use ClipRect with a Column inside it, but it doesn't seem to work well.
What I'd like to achieve is to clip the column's content and to show a text message if there is an overflow (if the column's content cannot be displayed within the available space).
Do you have any suggestions how I can make it happen?
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."),
),
),
],
),
),
);
}
}
Ellipsis: Use an Ellipsis (. . .) to indicate that text is overflow.
Solution : The solution to resolve this overflow error is to make your entire widget or in our case the Column scrollable. We can do that by wrapping our Column inside a SingleChildScrollView. Also, wrap the SingleChildScrollView with Center so that the entire UI is centered.
Clip clipBehavior. Controls how the contents of the dialog are clipped (or not) to the given shape. See the enum Clip for details of all possible options and their common use cases. Defaults to Clip. none, and must not be null.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With