Skip to content

Instantly share code, notes, and snippets.

@osaxma
Created December 22, 2019 17:32
Show Gist options
  • Save osaxma/dc735020351d72862713fd69e7ba1b96 to your computer and use it in GitHub Desktop.
Save osaxma/dc735020351d72862713fd69e7ba1b96 to your computer and use it in GitHub Desktop.
Flutter Backdrop Example for DartPad
// taken from: https://github.com/iampawan/FlutterBackdrop
// copy paste to https://dartpad.dev/ and should work
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.teal),
home: BackdropPage(),
));
}
class BackdropPage extends StatefulWidget {
@override
_BackdropPageState createState() => _BackdropPageState();
}
class _BackdropPageState extends State<BackdropPage>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: Duration(milliseconds: 100), value: 1.0);
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
bool get isPanelVisible {
final AnimationStatus status = controller.status;
return status == AnimationStatus.completed ||
status == AnimationStatus.forward;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Backdrop"),
elevation: 0.0,
actions: [IconButton(
onPressed: () {
controller.fling(velocity: isPanelVisible ? -1.0 : 1.0);
},
icon: new AnimatedIcon(
icon: AnimatedIcons.ellipsis_search,
progress: controller.view,
),
)],
),
body: new TwoPanels(
controller: controller,
),
);
}
}
// =============================================
class TwoPanels extends StatefulWidget {
final AnimationController controller;
TwoPanels({this.controller});
@override
_TwoPanelsState createState() => _TwoPanelsState();
}
class _TwoPanelsState extends State<TwoPanels> {
static const header_height = 32.0;
Animation<RelativeRect> getPanelAnimation(BoxConstraints constraints) {
final height = constraints.biggest.height;
final backPanelHeight = height - header_height;
final frontPanelHeight = -header_height;
return RelativeRectTween(
begin: RelativeRect.fromLTRB(
0.0, backPanelHeight, 0.0, frontPanelHeight),
end: RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0))
.animate(new CurvedAnimation(
parent: widget.controller, curve: Curves.linear));
}
Widget bothPanels(BuildContext context, BoxConstraints constraints) {
final ThemeData theme = Theme.of(context);
return Container(
child: Stack(
children: <Widget>[
Container(
color: theme.primaryColor,
child: Center(
child: Text(
"Back Panel",
style: TextStyle(fontSize: 24.0, color: Colors.white),
),
),
),
PositionedTransition(
rect: getPanelAnimation(constraints),
child: Material(
elevation: 12.0,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
topRight: Radius.circular(16.0)),
child: Column(
children: <Widget>[
Container(
height: header_height,
child: Center(
child: Text(
"Shop Here",
style: Theme.of(context).textTheme.button,
),
),
),
Expanded(
child: Center(
child: Text("Front Panel",
style:
TextStyle(fontSize: 24.0, color: Colors.black)),
),
)
],
),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: bothPanels,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment