Created
April 7, 2021 20:19
-
-
Save josh-burton/2afe8df2f7985745da7f533c5714c7bd to your computer and use it in GitHub Desktop.
split view overflow box
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file | |
// for details. All rights reserved. Use of this source code is governed by a | |
// BSD-style license that can be found in the LICENSE file. | |
import 'package:flutter/material.dart'; | |
import 'dart:math'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
debugShowCheckedModeBanner: false, | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: EnrolmentPage(), | |
); | |
} | |
} | |
class EnrolmentPage extends StatefulWidget { | |
@override | |
_EnrolmentPageState createState() => _EnrolmentPageState(); | |
} | |
class _EnrolmentPageState extends State<EnrolmentPage> { | |
final GlobalKey<FormState> _formKey = GlobalKey(); | |
@override | |
Widget build(BuildContext context) { | |
var theme = Theme.of(context); | |
return Padding( | |
padding: EdgeInsets.all(96), | |
child: Form( | |
key: _formKey, | |
child: Material( | |
color: Colors.white, | |
borderRadius: BorderRadius.circular(4), | |
clipBehavior: Clip.antiAlias, | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: [ | |
Container( | |
height: 72, | |
color: Colors.blue, | |
), | |
Expanded( | |
child: VerticalSplitView( | |
ratio: 0.5, | |
left: _UserDetails(), | |
right: _SeriesDetails(), | |
divider: Container( | |
width: 25, | |
color: Colors.grey, | |
), | |
), | |
), | |
const Divider( | |
height: 1, | |
thickness: 1, | |
), | |
], | |
), | |
), | |
), | |
); | |
} | |
} | |
class _UserDetails extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
var theme = Theme.of(context); | |
return SingleChildScrollView( | |
child: Padding( | |
padding: EdgeInsets.all(32), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.start, | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: [ | |
Text( | |
"User Details", | |
style: theme.textTheme.headline6, | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
class _SeriesDetails extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
var theme = Theme.of(context); | |
return OverflowBox( | |
minWidth: 300, | |
alignment: Alignment.centerLeft, | |
child: Container( | |
color: Colors.grey, | |
child: SingleChildScrollView( | |
padding: const EdgeInsets.all(16), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.start, | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: [ | |
Text( | |
"Series Details", | |
style: theme.textTheme.headline6.copyWith(color: Colors.grey), | |
), | |
], | |
), | |
), | |
), | |
); | |
} | |
} | |
class VerticalSplitView extends StatefulWidget { | |
final Widget left; | |
final Widget right; | |
final Widget divider; | |
final double ratio; | |
const VerticalSplitView( | |
{Key key, @required this.left, @required this.right, this.ratio = 0.7, @required this.divider}) | |
: assert(left != null), | |
assert(right != null), | |
assert(ratio >= 0), | |
assert(ratio <= 1), | |
super(key: key); | |
@override | |
_VerticalSplitViewState createState() => _VerticalSplitViewState(); | |
} | |
class _VerticalSplitViewState extends State<VerticalSplitView> { | |
double _ratio; | |
double get _leftWeight => max(30, min(98, _ratio * 100)); | |
double get _rightWeight => 100 - _leftWeight; | |
@override | |
void initState() { | |
super.initState(); | |
_ratio = widget.ratio; | |
} | |
@override | |
Widget build(BuildContext context) { | |
return LayoutBuilder(builder: (context, BoxConstraints constraints) { | |
return SizedBox( | |
width: constraints.maxWidth, | |
child: Row( | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
Expanded( | |
flex: _leftWeight.toInt(), | |
child: widget.left, | |
), | |
GestureDetector( | |
behavior: HitTestBehavior.translucent, | |
onPanUpdate: (DragUpdateDetails details) { | |
setState(() { | |
_ratio += details.delta.dx / constraints.maxWidth; | |
_ratio = _ratio.clamp(0, 1).toDouble(); | |
}); | |
}, | |
child: SizedBox( | |
height: constraints.maxHeight, | |
child: widget.divider, | |
), | |
), | |
Expanded( | |
flex: _rightWeight.toInt(), | |
child: widget.right, | |
), | |
], | |
), | |
); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment