Created
March 17, 2022 12:53
-
-
Save SuperPenguin/d6dc40640b74a1c05191d79ba01532df to your computer and use it in GitHub Desktop.
Flutter bottom sheet fill certain height
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
import 'package:flutter/material.dart'; | |
import 'dart:math' as math; | |
Future<void> main() async { | |
WidgetsFlutterBinding.ensureInitialized(); | |
runApp(const App()); | |
} | |
class App extends StatelessWidget { | |
const App({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData( | |
useMaterial3: true, | |
brightness: Brightness.light, | |
), | |
themeMode: ThemeMode.light, | |
initialRoute: '/', | |
routes: { | |
'/': (context) => const HomePage(), | |
}, | |
); | |
} | |
} | |
class HomePage extends StatefulWidget { | |
const HomePage({Key? key}) : super(key: key); | |
@override | |
State<HomePage> createState() => _HomePageState(); | |
} | |
class _HomePageState extends State<HomePage> { | |
final _bodyKey = GlobalKey(); | |
final _bottomKey = GlobalKey(); | |
double _topHeight = 200.0; | |
void _setHeight(double height) { | |
setState(() { | |
_topHeight = height; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Fill Sheet'), | |
), | |
body: Column( | |
key: _bodyKey, | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: [ | |
Container( | |
height: _topHeight, | |
color: Colors.pink, | |
alignment: Alignment.center, | |
child: Row( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
ElevatedButton( | |
onPressed: () => _setHeight(100), | |
child: const Text('100'), | |
), | |
const SizedBox(width: 8.0), | |
ElevatedButton( | |
onPressed: () => _setHeight(200), | |
child: const Text('200'), | |
), | |
const SizedBox(width: 8.0), | |
ElevatedButton( | |
onPressed: () => _setHeight(300), | |
child: const Text('300'), | |
), | |
], | |
), | |
), | |
Expanded( | |
child: SizedBox.expand( | |
key: _bottomKey, | |
child: ColoredBox( | |
color: Colors.grey, | |
child: Center( | |
child: Builder( | |
builder: (context) => ElevatedButton( | |
onPressed: () { | |
double initialSize = 0.25; | |
final bodyBox = _bodyKey.currentContext | |
?.findRenderObject() as RenderBox?; | |
final bottomBox = _bottomKey.currentContext | |
?.findRenderObject() as RenderBox?; | |
if (bodyBox != null && bottomBox != null) { | |
initialSize = | |
bottomBox.size.height / bodyBox.size.height; | |
} | |
initialSize = math.max(0.25, initialSize); | |
showBottomSheet( | |
context: context, | |
shape: const RoundedRectangleBorder( | |
borderRadius: BorderRadius.vertical( | |
top: Radius.circular(24.0), | |
), | |
), | |
builder: (context) => DraggableScrollableSheet( | |
initialChildSize: initialSize, | |
maxChildSize: 1, | |
minChildSize: 0.25, | |
expand: false, | |
builder: (context, controller) => Column( | |
children: [ | |
Container( | |
width: 100, | |
height: 8, | |
margin: const EdgeInsets.symmetric( | |
vertical: 10, | |
), | |
decoration: BoxDecoration( | |
borderRadius: BorderRadius.circular(20), | |
color: Colors.grey, | |
), | |
), | |
Expanded( | |
child: ListView.builder( | |
controller: controller, | |
itemCount: 100, | |
itemBuilder: (context, index) => ListTile( | |
title: Text('Item $index'), | |
), | |
), | |
), | |
], | |
), | |
), | |
); | |
}, | |
child: const Text('Show Sheet'), | |
), | |
), | |
), | |
), | |
), | |
), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment