|
1 | | -import 'package:flutter/gestures.dart'; |
2 | 1 | import 'package:flutter/material.dart'; |
3 | 2 |
|
4 | | -class MaxWidthBox extends StatefulWidget { |
| 3 | +class MaxWidthBox extends StatelessWidget { |
5 | 4 | final double? maxWidth; |
| 5 | + final Widget child; |
6 | 6 |
|
7 | | - /// Control the internal Stack alignment. This widget |
8 | | - /// uses a Stack to set the widget to max width on top of |
9 | | - /// a background. |
| 7 | + /// Control child alignment. |
10 | 8 | /// Defaults to [Alignment.topCenter] because app |
11 | 9 | /// content is usually top aligned. |
12 | 10 | final AlignmentGeometry alignment; |
13 | | - final Widget child; |
14 | | - final Widget? background; |
| 11 | + final EdgeInsets? padding; |
| 12 | + final Color? backgroundColor; |
15 | 13 |
|
16 | 14 | const MaxWidthBox( |
17 | 15 | {super.key, |
18 | 16 | required this.maxWidth, |
19 | 17 | required this.child, |
20 | | - this.background, |
21 | | - this.alignment = Alignment.topCenter}); |
22 | | - |
23 | | - @override |
24 | | - State<MaxWidthBox> createState() => _MaxWidthBoxState(); |
25 | | -} |
26 | | - |
27 | | -class _MaxWidthBoxState extends State<MaxWidthBox> { |
28 | | - final _scrollController = ScrollController(); |
| 18 | + this.alignment = Alignment.topCenter, |
| 19 | + this.padding, |
| 20 | + this.backgroundColor}); |
29 | 21 |
|
30 | 22 | @override |
31 | 23 | Widget build(BuildContext context) { |
32 | 24 | MediaQueryData mediaQuery = MediaQuery.of(context); |
33 | 25 |
|
34 | | - if (widget.maxWidth != null) { |
35 | | - if (mediaQuery.size.width > widget.maxWidth!) { |
| 26 | + if (maxWidth != null) { |
| 27 | + if (mediaQuery.size.width > maxWidth!) { |
36 | 28 | mediaQuery = mediaQuery.copyWith( |
37 | | - size: Size(widget.maxWidth!, mediaQuery.size.height)); |
| 29 | + size: Size(maxWidth! - (padding?.horizontal ?? 0), |
| 30 | + mediaQuery.size.height - (padding?.vertical ?? 0))); |
38 | 31 | } |
39 | 32 | } |
40 | 33 |
|
41 | | - return Stack( |
42 | | - alignment: widget.alignment, |
43 | | - children: [ |
44 | | - Scrollbar( |
45 | | - controller: _scrollController, |
46 | | - trackVisibility: true, |
47 | | - thumbVisibility: true, |
48 | | - child: Listener( |
49 | | - onPointerSignal: (pointerSignal) { |
50 | | - if (pointerSignal is PointerScrollEvent) { |
51 | | - final newOffset = |
52 | | - _scrollController.offset + pointerSignal.scrollDelta.dy; |
53 | | - |
54 | | - if (newOffset < _scrollController.position.minScrollExtent) { |
55 | | - _scrollController |
56 | | - .jumpTo(_scrollController.position.minScrollExtent); |
57 | | - } else if (newOffset >= |
58 | | - _scrollController.position.minScrollExtent && |
59 | | - newOffset <= _scrollController.position.maxScrollExtent) { |
60 | | - _scrollController.jumpTo(newOffset); |
61 | | - } else if (newOffset > |
62 | | - _scrollController.position.maxScrollExtent) { |
63 | | - _scrollController |
64 | | - .jumpTo(_scrollController.position.maxScrollExtent); |
65 | | - } |
66 | | - } |
67 | | - }, |
68 | | - child: widget.background ?? |
69 | | - Container( |
70 | | - width: double.infinity, |
71 | | - height: double.infinity, |
72 | | - color: Colors.transparent), |
| 34 | + return Align( |
| 35 | + alignment: alignment, |
| 36 | + child: ConstrainedBox( |
| 37 | + constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity), |
| 38 | + child: Container( |
| 39 | + color: backgroundColor, |
| 40 | + padding: padding, |
| 41 | + child: MediaQuery( |
| 42 | + data: mediaQuery, |
| 43 | + child: child, |
73 | 44 | ), |
74 | 45 | ), |
75 | | - MediaQuery( |
76 | | - data: mediaQuery, |
77 | | - child: SizedBox( |
78 | | - width: widget.maxWidth, |
79 | | - child: PrimaryScrollController( |
80 | | - controller: _scrollController, |
81 | | - child: widget.child, |
82 | | - ), |
83 | | - ), |
84 | | - ), |
85 | | - ], |
| 46 | + ), |
86 | 47 | ); |
87 | 48 | } |
88 | | - |
89 | | - @override |
90 | | - void dispose() { |
91 | | - _scrollController.dispose(); |
92 | | - super.dispose(); |
93 | | - } |
94 | 49 | } |
95 | | - |
96 | | -// NotificationListener<ScrollNotification>( |
97 | | -// onNotification: (scrollNotification) { |
98 | | -// // Forward the scroll notification to the child |
99 | | -// if (scrollNotification is ScrollUpdateNotification) { |
100 | | -// _scrollController.jumpTo(_scrollController.offset + |
101 | | -// scrollNotification.scrollDelta!.toDouble()); |
102 | | -// } |
103 | | -// return false; // Don't consume the notification |
104 | | -// }, |
105 | | -// child: widget.background ?? |
106 | | -// Container( |
107 | | -// width: double.infinity, |
108 | | -// height: double.infinity, |
109 | | -// color: Colors.transparent), |
110 | | -// ), |
0 commit comments