Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue-96] Fix TopBar Widget keeps being visible after Keyboard hides #119

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,24 @@ import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';
///
/// This widget is responsible for displaying the main content of the scrollable modal sheet.
/// It handles the scroll behavior, page layout, and interactions within the modal sheet.
class WoltModalSheetMainContent extends StatefulWidget {
final ValueNotifier<double> currentScrollPosition;
class WoltModalSheetMainContent extends StatelessWidget {
final ScrollController? scrollController;
final GlobalKey pageTitleKey;
final SliverWoltModalSheetPage page;
final WoltModalType woltModalType;

const WoltModalSheetMainContent({
required this.currentScrollPosition,
required this.scrollController,
required this.pageTitleKey,
required this.page,
required this.woltModalType,
Key? key,
}) : super(key: key);

@override
State<WoltModalSheetMainContent> createState() =>
_WoltModalSheetMainContentState();
}

class _WoltModalSheetMainContentState extends State<WoltModalSheetMainContent> {
late ScrollController scrollController;

@override
void initState() {
super.initState();
scrollController = widget.page.scrollController ??
ScrollController(
initialScrollOffset: widget.currentScrollPosition.value);
}

@override
Widget build(BuildContext context) {
final themeData = Theme.of(context).extension<WoltModalSheetThemeData>();
final defaultThemeData = WoltModalSheetDefaultThemeData(context);
final page = widget.page;
final heroImageHeight = page.heroImage == null
? 0.0
: (page.heroImageHeight ??
Expand Down Expand Up @@ -85,7 +68,7 @@ class _WoltModalSheetMainContentState extends State<WoltModalSheetMainContent> {
} else {
final pageTitle = page.pageTitle;
return KeyedSubtree(
key: widget.pageTitleKey,
key: pageTitleKey,
child: pageTitle ?? const SizedBox.shrink(),
);
}
Expand All @@ -101,24 +84,12 @@ class _WoltModalSheetMainContentState extends State<WoltModalSheetMainContent> {
),
],
);
return NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
final isVerticalScrollNotification =
scrollNotification is ScrollUpdateNotification &&
scrollNotification.metrics.axis == Axis.vertical;
if (isVerticalScrollNotification) {
widget.currentScrollPosition.value =
scrollNotification.metrics.pixels;
}
return false;
},
child: Padding(
// The scroll view should be padded by the height of the top bar layer if it's always
// visible. Otherwise, over scroll effect will not be visible due to the top bar layer.
padding:
EdgeInsets.only(top: isTopBarLayerAlwaysVisible ? topBarHeight : 0),
child: scrollView,
),
return Padding(
// The scroll view should be padded by the height of the top bar layer if it's always
// visible. Otherwise, over scroll effect will not be visible due to the top bar layer.
padding:
EdgeInsets.only(top: isTopBarLayerAlwaysVisible ? topBarHeight : 0),
child: scrollView,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,30 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:wolt_modal_sheet/src/content/components/main_content/wolt_modal_sheet_top_bar.dart';
import 'package:wolt_modal_sheet/src/theme/wolt_modal_sheet_default_theme_data.dart';
import 'package:wolt_modal_sheet/src/utils/soft_keyboard_closed_event.dart';
import 'package:wolt_modal_sheet/src/utils/wolt_layout_transformation_utils.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

/// `WoltModalSheetTopBarFlow` controls the top bar behavior within the modal sheet page
/// provided by the [WoltModalSheetPage] when `isTopBarLayerAlwaysVisible` is set to true.
/// [WoltModalSheetTopBarFlow] controls the top bar behavior within the modal sheet page
/// provided by the [WoltModalSheetPage] when `isTopBarLayerAlwaysVisible` is set to false.
///
/// It is responsible for the positioning, translation, and opacity of the top bar as the user
/// scrolls through the content. Utilizing the [Flow] widget, it listens to the current scroll
/// position and performs transformations to achieve the desired effects on the top bar, such as
/// fading in/out and translating vertically.
/// position and soft keyboard closing events, then, performs transformations to achieve the
/// desired effects on the top bar, such as fading in/out and translating vertically.
class WoltModalSheetTopBarFlow extends StatelessWidget {
final ValueListenable<double> currentScrollPositionListenable;
final ScrollController scrollController;
final GlobalKey titleKey;
final double topBarTranslationYAmountInPx;
final SliverWoltModalSheetPage page;
final ValueListenable<SoftKeyboardClosedEvent> softKeyboardClosedListenable;

const WoltModalSheetTopBarFlow({
required this.page,
required this.currentScrollPositionListenable,
required this.scrollController,
required this.titleKey,
required this.topBarTranslationYAmountInPx,
required this.softKeyboardClosedListenable,
Key? key,
}) : super(key: key);

Expand All @@ -43,10 +46,10 @@ class WoltModalSheetTopBarFlow extends StatelessWidget {
delegate: _TopBarFlowDelegate(
topBarHeight: topBarHeight,
heroImageHeight: heroImageHeight,
currentScrollPositionListenable: currentScrollPositionListenable,
scrollController: scrollController,
titleKey: titleKey,
topBarTranslationYAmountInPx: topBarTranslationYAmountInPx,
buildContext: context,
softKeyboardClosedListenable: softKeyboardClosedListenable,
),
children: [WoltModalSheetTopBar(page: page)],
);
Expand All @@ -56,21 +59,26 @@ class WoltModalSheetTopBarFlow extends StatelessWidget {
class _TopBarFlowDelegate extends FlowDelegate {
final double topBarHeight;
final double heroImageHeight;
final ValueListenable<double> currentScrollPositionListenable;
final ScrollController scrollController;
final GlobalKey titleKey;
final double topBarTranslationYAmountInPx;
final BuildContext buildContext;
final ValueListenable<SoftKeyboardClosedEvent> softKeyboardClosedListenable;

_TopBarFlowDelegate({
required this.topBarHeight,
required this.heroImageHeight,
required this.currentScrollPositionListenable,
required this.scrollController,
required this.titleKey,
required this.topBarTranslationYAmountInPx,
required this.buildContext,
}) : super(repaint: currentScrollPositionListenable);
required this.softKeyboardClosedListenable,
}) : super(
repaint: Listenable.merge([
scrollController,
softKeyboardClosedListenable,
]),
);

double get currentScrollPosition => currentScrollPositionListenable.value;
double get currentScrollOffset => scrollController.position.pixels;

@override
void paintChildren(FlowPaintingContext context) {
Expand All @@ -86,7 +94,7 @@ class _TopBarFlowDelegate extends FlowDelegate {
WoltLayoutTransformationUtils.calculateTransformationValue(
rangeInPx: 8 + pageTitleHeight,
progressInRangeInPx:
currentScrollPosition - topBarTranslationYAndOpacityStartPoint,
currentScrollOffset - topBarTranslationYAndOpacityStartPoint,
startValue: topBarTranslationYStart,
endValue: topBarTranslationYEnd,
);
Expand All @@ -96,7 +104,7 @@ class _TopBarFlowDelegate extends FlowDelegate {
WoltLayoutTransformationUtils.calculateTransformationValue(
rangeInPx: 8,
progressInRangeInPx:
currentScrollPosition - topBarTranslationYAndOpacityStartPoint,
currentScrollOffset - topBarTranslationYAndOpacityStartPoint,
startValue: 0.0,
endValue: 1.0,
);
Expand All @@ -113,9 +121,11 @@ class _TopBarFlowDelegate extends FlowDelegate {
bool shouldRepaint(covariant _TopBarFlowDelegate oldDelegate) {
return heroImageHeight != oldDelegate.heroImageHeight ||
titleKey != oldDelegate.titleKey ||
currentScrollPosition != oldDelegate.currentScrollPosition ||
currentScrollOffset != oldDelegate.currentScrollOffset ||
topBarTranslationYAmountInPx !=
oldDelegate.topBarTranslationYAmountInPx ||
softKeyboardClosedListenable.value !=
oldDelegate.softKeyboardClosedListenable.value ||
topBarHeight != oldDelegate.topBarHeight;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:wolt_modal_sheet/src/theme/wolt_modal_sheet_default_theme_data.dart';
import 'package:wolt_modal_sheet/src/utils/soft_keyboard_closed_event.dart';
import 'package:wolt_modal_sheet/src/utils/wolt_layout_transformation_utils.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

/// This class represents the top bar title behavior within a modal sheet page.
/// [WoltModalSheetTopBarTitleFlow] controls the top bar title behavior within the modal sheet page
/// provided by the [WoltModalSheetPage] when `isTopBarLayerAlwaysVisible` is set to false.
///
/// It is responsible for the positioning, translation, and opacity of the top bar title as the user
/// scrolls through the content. Utilizing the [Flow] widget, it listens to the current scroll
/// position and soft keyboard closing events, then, performs transformations to achieve the
/// desired effects on the top bar title, such as fading in/out and translating vertically.
class WoltModalSheetTopBarTitleFlow extends StatelessWidget {
final ValueListenable<double> currentScrollPositionListenable;
final ScrollController scrollController;
final GlobalKey titleKey;
final SliverWoltModalSheetPage page;
final Widget topBarTitle;
final ValueListenable<SoftKeyboardClosedEvent> softKeyboardClosedListenable;

const WoltModalSheetTopBarTitleFlow({
required this.page,
required this.currentScrollPositionListenable,
required this.scrollController,
required this.titleKey,
required this.topBarTitle,
required this.softKeyboardClosedListenable,
Key? key,
}) : super(key: key);

Expand All @@ -37,9 +46,9 @@ class WoltModalSheetTopBarTitleFlow extends StatelessWidget {
delegate: _TopBarTitleFlowDelegate(
topBarHeight: topBarHeight,
heroImageHeight: heroImageHeight,
currentScrollPositionListenable: currentScrollPositionListenable,
scrollController: scrollController,
titleKey: titleKey,
buildContext: context,
softKeyboardClosedNotifier: softKeyboardClosedListenable,
),
children: [Center(child: topBarTitle)],
);
Expand All @@ -49,19 +58,24 @@ class WoltModalSheetTopBarTitleFlow extends StatelessWidget {
class _TopBarTitleFlowDelegate extends FlowDelegate {
final double topBarHeight;
final double heroImageHeight;
final ValueListenable<double> currentScrollPositionListenable;
final ScrollController scrollController;
final GlobalKey titleKey;
final BuildContext buildContext;
final ValueListenable<SoftKeyboardClosedEvent> softKeyboardClosedNotifier;

_TopBarTitleFlowDelegate({
required this.topBarHeight,
required this.heroImageHeight,
required this.currentScrollPositionListenable,
required this.scrollController,
required this.titleKey,
required this.buildContext,
}) : super(repaint: currentScrollPositionListenable);
required this.softKeyboardClosedNotifier,
}) : super(
repaint: Listenable.merge([
scrollController,
softKeyboardClosedNotifier,
]),
);

double get currentScrollPosition => currentScrollPositionListenable.value;
double get currentScrollPosition => scrollController.position.pixels;

@override
void paintChildren(FlowPaintingContext context) {
Expand Down Expand Up @@ -108,7 +122,10 @@ class _TopBarTitleFlowDelegate extends FlowDelegate {
bool shouldRepaint(covariant _TopBarTitleFlowDelegate oldDelegate) {
return heroImageHeight != oldDelegate.heroImageHeight ||
titleKey != oldDelegate.titleKey ||
currentScrollPosition != oldDelegate.currentScrollPosition ||
scrollController.position.pixels !=
oldDelegate.scrollController.position.pixels ||
softKeyboardClosedNotifier.value !=
oldDelegate.softKeyboardClosedNotifier.value ||
topBarHeight != oldDelegate.topBarHeight;
}
}
Loading