151 lines
5.1 KiB
Dart
151 lines
5.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:furman_now/src/utils/conditional_parent_widget.dart';
|
|
import 'package:furman_now/src/utils/theme.dart';
|
|
import 'package:furman_now/src/widgets/scroll_view_height.dart';
|
|
import 'package:transparent_pointer/transparent_pointer.dart';
|
|
|
|
class AppPageLayout extends StatefulWidget {
|
|
final IconData icon;
|
|
final String title;
|
|
final Color? backgroundColor;
|
|
final Widget content;
|
|
final void Function()? iconTapAction;
|
|
final bool darkStatusBar;
|
|
|
|
const AppPageLayout({
|
|
required this.title,
|
|
required this.icon,
|
|
this.backgroundColor,
|
|
required this.content,
|
|
this.iconTapAction,
|
|
this.darkStatusBar = true,
|
|
Key? key,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<AppPageLayout> createState() => _AppPageLayoutState();
|
|
}
|
|
|
|
class _AppPageLayoutState extends State<AppPageLayout> {
|
|
final ScrollController _controller = ScrollController();
|
|
double overscrollBoxHeight = 0;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
_controller.addListener(updateScrollPosition);
|
|
}
|
|
|
|
updateScrollPosition() {
|
|
if (_controller.position.pixels > _controller.position.maxScrollExtent) {
|
|
setState(() {
|
|
overscrollBoxHeight =
|
|
_controller.position.pixels - _controller.position.maxScrollExtent;
|
|
});
|
|
} else {
|
|
if (overscrollBoxHeight != 0) {
|
|
setState(() {
|
|
overscrollBoxHeight = 0;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: AnnotatedRegion<SystemUiOverlayStyle>(
|
|
value: SystemUiOverlayStyle(
|
|
statusBarColor: Colors.transparent,
|
|
systemNavigationBarContrastEnforced: true,
|
|
statusBarIconBrightness: widget.darkStatusBar
|
|
? Brightness.dark
|
|
: Brightness.light,
|
|
statusBarBrightness: widget.darkStatusBar
|
|
? Brightness.light
|
|
: Brightness.dark,
|
|
),
|
|
child: Container(
|
|
color: widget.backgroundColor ?? Colors.grey[100],
|
|
child: SafeArea(
|
|
child: Stack(
|
|
fit: StackFit.loose,
|
|
children: [
|
|
SizedBox(
|
|
width: double.infinity,
|
|
height: double.infinity,
|
|
child: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 30),
|
|
width: double.infinity,
|
|
height: 100,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Wrap(
|
|
crossAxisAlignment: WrapCrossAlignment.center,
|
|
children: [
|
|
ConditionalParentWidget(
|
|
condition: widget.iconTapAction != null,
|
|
conditionalBuilder: (child) => GestureDetector(
|
|
onTap: widget.iconTapAction!,
|
|
child: child,
|
|
),
|
|
child: Icon(
|
|
widget.icon,
|
|
size: 35,
|
|
color: Colors.grey[700]
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
widget.title,
|
|
style: furmanTextStyle(TextStyle(
|
|
color: Colors.grey[900],
|
|
fontSize: 28, fontWeight: FontWeight.w700
|
|
)),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
// makes the overscroll color at the bottom match
|
|
// that of the navbar
|
|
Align(
|
|
alignment: Alignment.bottomCenter,
|
|
child: Container(
|
|
height: 30 + overscrollBoxHeight,
|
|
color: Colors.grey.shade50,
|
|
),
|
|
),
|
|
TransparentPointer(
|
|
child: ScrollViewWithHeight(
|
|
controller: _controller,
|
|
child: Container(
|
|
decoration: const BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.all(Radius.circular(30)),
|
|
),
|
|
// padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
|
|
margin: const EdgeInsets.only(top: 100),
|
|
width: double.infinity,
|
|
child: widget.content,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|