Skip to content

Instantly share code, notes, and snippets.

@sorgfal
Last active October 5, 2022 13:21
Show Gist options
  • Select an option

  • Save sorgfal/217301cc4ba15123c3aad2a79d28c902 to your computer and use it in GitHub Desktop.

Select an option

Save sorgfal/217301cc4ba15123c3aad2a79d28c902 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
void main() {
runApp(const Myapp());
}
class Myapp extends StatelessWidget {
const Myapp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHome(),
);
}
}
class MyHome extends StatefulWidget {
const MyHome({super.key});
@override
State<MyHome> createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> with TickerProviderStateMixin {
late final AnimatedLinkedAppBarBottomSheet showingState;
@override
void initState() {
super.initState();
showingState = AnimatedLinkedAppBarBottomSheet(vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: LinkedAppBarBottomSheet(
showingState: showingState,
hiddenTopBarHeight: kToolbarHeight,
topBar: Container(
height: kToolbarHeight * 2,
color: Colors.cyan,
),
topBarHeight: kToolbarHeight * 2,
bottomSheetHeight: 400,
bottomSheet: Container(
height: 400,
color: Colors.blue,
child: ListView(
children: [
for (var i = 0; i < 10; i++)
ListTile(
title: Text('Number $i'),
)
],
)),
child: ListView.builder(
itemBuilder: ((context, index) => ListTile(
title: Text(index.toString()),
)),
)),
);
}
}
class AnimatedLinkedAppBarBottomSheet extends AnimationController {
AnimatedLinkedAppBarBottomSheet({required super.vsync})
: super(duration: Duration(milliseconds: 300));
setHideStatus(double v) {
if (value >= 0 && value <= 1) {
value += v;
}
}
endMotion() {
if (value > .5) {
animateTo(1);
}
if (value < .5) {
animateTo(0);
}
}
}
class LinkedAppBarBottomSheet extends StatefulWidget {
/// То что будет под барами
final Widget child;
/// Высота верхней полоcки, которая будет видима в скрытом состоянии
final double hiddenTopBarHeight;
/// Высота верхней полоcки, которая будет видима в открытом состоянии
final double topBarHeight;
/// Высота нижнего щита, который будет видим в открытом состоянии
final double bottomSheetHeight;
/// Виджет верхней полоски
final Widget topBar;
/// Виджет нищнего листа
final Widget bottomSheet;
/// Высота полоски, которая будет видна снизу и за которую можно тянуть
final double bottomDraggableSheetHeight;
final AnimatedLinkedAppBarBottomSheet showingState;
const LinkedAppBarBottomSheet({
super.key,
required this.child,
required this.topBar,
required this.bottomSheet,
required this.topBarHeight,
required this.bottomSheetHeight,
required this.showingState,
required this.hiddenTopBarHeight,
this.bottomDraggableSheetHeight = 10,
});
@override
State<LinkedAppBarBottomSheet> createState() =>
_LinkedAppBarBottomSheetState();
}
class _LinkedAppBarBottomSheetState extends State<LinkedAppBarBottomSheet> {
onPanEnd(DragEndDetails ded) {
widget.showingState.endMotion();
}
onPanUpdate(DragUpdateDetails dud) {
var diffKoef = dud.delta.dy / (widget.bottomSheetHeight);
_updateValue(diffKoef);
}
_updateValue(double diff) {
widget.showingState.setHideStatus(diff);
}
@override
Widget build(BuildContext context) {
var bottomBaseYOffset =
MediaQuery.of(context).size.height - widget.bottomSheetHeight;
return Stack(
children: [
widget.child,
AnimatedBuilder(
animation: widget.showingState,
builder: (context, child) => Transform.translate(
offset: Offset(
0,
(bottomBaseYOffset -
(widget.bottomDraggableSheetHeight *
widget.showingState.value) +
widget.bottomSheetHeight * widget.showingState.value)),
child: GestureDetector(
onPanEnd: onPanEnd,
onPanUpdate: onPanUpdate,
child: Opacity(
opacity: 1 - (0.5 * widget.showingState.value),
child: widget.bottomSheet)),
),
),
AnimatedBuilder(
animation: widget.showingState,
builder: (context, child) => Transform.translate(
offset: Offset(
0,
((-widget.topBarHeight + widget.hiddenTopBarHeight) *
widget.showingState.value)),
child: widget.topBar,
),
),
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment