Skip to content

Instantly share code, notes, and snippets.

@slightfoot
Forked from austinstoker/main.dart
Last active June 12, 2024 21:29
Show Gist options
  • Save slightfoot/a8d97045cd21a4bcd9e5098026d1dba2 to your computer and use it in GitHub Desktop.
Save slightfoot/a8d97045cd21a4bcd9e5098026d1dba2 to your computer and use it in GitHub Desktop.
Force Intrinsics - by Simon Lightfoot - Humpday Q&A :: 12th June 2024 #Flutter #Dart - https://www.youtube.com/watch?v=QBmqKvw_0s8
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: SingleChildScrollViewExample(),
);
}
}
class SingleChildScrollViewExample extends StatelessWidget {
const SingleChildScrollViewExample({super.key});
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyMedium!,
child: ColoredBox(
color: Colors.white,
child: Center(
child: SizedBox(
height: 400,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
const Text('Header stuff'),
IntrinsicHeight(
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
),
child: const Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Checklist(),
),
Expanded(
child: WorkArea(),
),
],
),
),
),
],
),
),
),
),
),
),
),
);
}
}
class Checklist extends StatefulWidget {
const Checklist({super.key});
@override
State<Checklist> createState() => _ChecklistState();
}
class _ChecklistState extends State<Checklist> {
int _numberOfItems = 10;
void adjustItemCount(int amount) {
setState(() {
_numberOfItems = (_numberOfItems + amount) //
.clamp(0, 100);
});
}
@override
Widget build(BuildContext context) {
return ForceIntrinsics(
width: 0,
height: 0,
child: CustomScrollView(
physics: const ClampingScrollPhysics(),
slivers: [
SliverToBoxAdapter(
child: Row(
children: [
ElevatedButton(
onPressed: () => adjustItemCount(-1),
child: const Text('-'),
),
Text(_numberOfItems.toString()),
ElevatedButton(
onPressed: () => adjustItemCount(1),
child: const Text('+'),
),
],
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
childCount: _numberOfItems,
(BuildContext context, int index) {
return Material(
child: Container(
color: Colors.red,
child: SizedBox(
height: 25,
width: 100,
child: Checkbox(
value: false,
//Yes, I know they don't work, that's ok for this example.
onChanged: (bool? value) {},
),
),
),
);
},
),
),
],
),
);
}
}
class WorkArea extends StatefulWidget {
const WorkArea({super.key});
@override
State<WorkArea> createState() => _WorkAreaState();
}
class _WorkAreaState extends State<WorkArea> {
double _height = 200;
void adjustHeight(double amount) {
setState(() {
_height = (_height + amount).clamp(0, 500);
});
}
@override
Widget build(BuildContext context) {
return ColoredBox(
color: Colors.teal,
child: SizedBox(
height: _height,
child: Row(
children: [
ElevatedButton(
onPressed: () => adjustHeight(-50),
child: const Text('-'),
),
Text(_height.toString()),
ElevatedButton(
onPressed: () => adjustHeight(50),
child: const Text('+'),
),
],
),
),
);
}
}
class ForceIntrinsics extends SingleChildRenderObjectWidget {
const ForceIntrinsics({
super.key,
this.width,
this.height,
required super.child,
});
final double? width;
final double? height;
@override
RenderObject createRenderObject(BuildContext context) {
return RenderForceIntrinsics(
width: width,
height: height,
);
}
@override
void updateRenderObject(
BuildContext context, covariant RenderForceIntrinsics renderObject) {
renderObject
..width = width
..height = height;
}
}
class RenderForceIntrinsics extends RenderProxyBox {
RenderForceIntrinsics({
double? width,
double? height,
}) : _width = width,
_height = height;
double? _width;
double? _height;
double? get width => _width;
set width(double? value) {
if (_width != value) {
_width = value;
markNeedsLayout();
}
}
double? get height => _height;
set height(double? value) {
if (_height != value) {
_height = value;
markNeedsLayout();
}
}
@override
double getMinIntrinsicHeight(double width) {
if (_height case double height) {
return height;
}
return super.getMinIntrinsicHeight(width);
}
@override
double getMaxIntrinsicHeight(double width) {
if (_height case double height) {
return height;
}
return super.getMaxIntrinsicHeight(width);
}
@override
double getMinIntrinsicWidth(double height) {
if (_width case double width) {
return width;
}
return super.getMinIntrinsicWidth(height);
}
@override
double getMaxIntrinsicWidth(double height) {
if (_width case double width) {
return width;
}
return super.getMaxIntrinsicWidth(height);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment