Skip to content

Instantly share code, notes, and snippets.

@TahaTesser
Created May 26, 2024 21:59
Show Gist options
  • Save TahaTesser/3aa8330fea3605a8415d14f663bf35d9 to your computer and use it in GitHub Desktop.
Save TahaTesser/3aa8330fea3605a8415d14f663bf35d9 to your computer and use it in GitHub Desktop.
Intrinsic Horizontal Stadium from Flutter Badge widget source code
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Width: 100 - height: 20',
style: Theme.of(context).textTheme.titleLarge),
Text('Without _IntrinsicHorizontalStadium', style: Theme.of(context).textTheme.titleMedium),
DecoratedBox(
decoration: const ShapeDecoration(
color: Colors.red, shape: StadiumBorder()),
child: SizedBox.fromSize(
size: const Size(100, 20),
),
),
Text('With _IntrinsicHorizontalStadium', style: Theme.of(context).textTheme.titleMedium),
_IntrinsicHorizontalStadium(
minSize: 50,
child: DecoratedBox(
decoration: const ShapeDecoration(
color: Colors.red, shape: StadiumBorder()),
child: SizedBox.fromSize(
size: const Size(100, 20),
),
),
),
],
),
const VerticalDivider(),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Width: 20 - height: 100',
style: Theme.of(context).textTheme.headlineSmall),
Text('Without _IntrinsicHorizontalStadium', style: Theme.of(context).textTheme.titleMedium),
DecoratedBox(
decoration: const ShapeDecoration(
color: Colors.red, shape: StadiumBorder()),
child: SizedBox.fromSize(
size: const Size(20, 100),
),
),
Text('With _IntrinsicHorizontalStadium', style: Theme.of(context).textTheme.titleMedium),
_IntrinsicHorizontalStadium(
minSize: 50,
child: DecoratedBox(
decoration: const ShapeDecoration(
color: Colors.red, shape: StadiumBorder()),
child: SizedBox.fromSize(
size: const Size(20, 100),
),
),
),
],
),
],
),
),
);
}
}
class _IntrinsicHorizontalStadium extends SingleChildRenderObjectWidget {
const _IntrinsicHorizontalStadium({super.child, required this.minSize});
final double minSize;
@override
_RenderIntrinsicHorizontalStadium createRenderObject(BuildContext context) {
return _RenderIntrinsicHorizontalStadium(minSize: minSize);
}
}
class _RenderIntrinsicHorizontalStadium extends RenderProxyBox {
_RenderIntrinsicHorizontalStadium({
RenderBox? child,
required double minSize,
}) : _minSize = minSize,
super(child);
double get minSize => _minSize;
double _minSize;
set minSize(double value) {
if (_minSize == value) {
return;
}
_minSize = value;
markNeedsLayout();
}
@override
double computeMinIntrinsicWidth(double height) {
return getMaxIntrinsicWidth(height);
}
@override
double computeMaxIntrinsicWidth(double height) {
return math.max(getMaxIntrinsicHeight(double.infinity),
super.computeMaxIntrinsicWidth(height));
}
@override
double computeMinIntrinsicHeight(double width) {
return getMaxIntrinsicHeight(width);
}
@override
double computeMaxIntrinsicHeight(double width) {
return math.max(minSize, super.computeMaxIntrinsicHeight(width));
}
BoxConstraints _childConstraints(
RenderBox child, BoxConstraints constraints) {
final double childHeight =
math.max(minSize, child.getMaxIntrinsicHeight(constraints.maxWidth));
final double childWidth = child.getMaxIntrinsicWidth(constraints.maxHeight);
return constraints.tighten(
width: math.max(childWidth, childHeight), height: childHeight);
}
Size _computeSize(
{required ChildLayouter layoutChild,
required BoxConstraints constraints}) {
final RenderBox child = this.child!;
final Size childSize =
layoutChild(child, _childConstraints(child, constraints));
if (childSize.height > childSize.width) {
return Size(childSize.height, childSize.height);
}
return childSize;
}
@override
@protected
Size computeDryLayout(covariant BoxConstraints constraints) {
return _computeSize(
layoutChild: ChildLayoutHelper.dryLayoutChild,
constraints: constraints,
);
}
@override
double? computeDryBaseline(
BoxConstraints constraints, TextBaseline baseline) {
final RenderBox child = this.child!;
return child.getDryBaseline(
_childConstraints(child, constraints), baseline);
}
@override
void performLayout() {
size = _computeSize(
layoutChild: ChildLayoutHelper.layoutChild,
constraints: constraints,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment