fujidaiti / smooth_sheets

Sheet widgets with smooth motion and great flexibility.
https://pub.dev/packages/smooth_sheets
MIT License
225 stars 22 forks source link

Encounter KeyboardIssue when opening ScrollableSheet #65

Closed Tommy-Wang0602 closed 7 months ago

Tommy-Wang0602 commented 7 months ago

Hi ~ @fujidaiti

As shown as video I've been encountering some issues with ScrollableSheet ,I'm not sure if it's a bug or a layout problem. Due to certain reasons, I need to have the ScrollableSheet appear in the same layer view using a Stack. However, I've been struggling to find a way to prevent the ScrollableSheet from displaying a spring-like animation when the keyboard opens. I'm seeking advice on how to solve this problem.

I've included the code I've been using below for reference.

https://github.com/fujidaiti/smooth_sheets/assets/133644139/ff22dcf4-e4c4-4412-85bd-7f1234e8aad6

class MobileCalendarAddItemBottomSheet extends StatefulWidget {
  const MobileCalendarAddItemBottomSheet({super.key, required this.context});

  final BuildContext context;

  @override
  State<MobileCalendarAddItemBottomSheet> createState() =>
      _MobileCalendarAddItemBottomSheetState();
}

class _MobileCalendarAddItemBottomSheetState
    extends State<MobileCalendarAddItemBottomSheet> {
  final FocusNode focusNode = FocusNode();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Future.delayed(const Duration(milliseconds: 100), () {
        FocusScope.of(context).requestFocus(focusNode);
      });
    });
  }

  @override
  void dispose() {
    focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    const maxAnchor = Extent.proportional(1.0);
    const secondAnchor = Extent.pixels(185);
    const sheetShape = BoxDecoration(
      borderRadius: BorderRadius.vertical(top: const Radius.circular(16.0)),
      color: Colors.black,
      boxShadow: [
        BoxShadow(
          color: Colors.black45,
          spreadRadius: 2,
          blurRadius: 2,
        ),
      ],
    );

    final systemUiInsets = MediaQuery.of(context).padding;
    return SafeArea(
      bottom: false,
      maintainBottomViewPadding: true,
      child: ScrollableSheet(
        controller: Get.find<CalendarAddItemController>()
            .mobileCalendarAddItemBottomSheetController,
        initialExtent: (Get.find<MaiCalendarController>()
                        .sfCalendarController
                        .value
                        .view ==
                    CalendarView.week ||
                Get.find<MaiCalendarController>()
                        .sfCalendarController
                        .value
                        .view ==
                    CalendarView.day ||
                Get.find<MaiCalendarController>()
                        .sfCalendarController
                        .value
                        .view ==
                    CalendarView.schedule)
            ? secondAnchor
            : maxAnchor,
        maxExtent: maxAnchor,
        minExtent: Extent.pixels(systemUiInsets.bottom),
        physics: StretchingSheetPhysics(
          stretchingRange: const Extent.proportional(0),
          parent: SnappingSheetPhysics(
            snappingBehavior: SnapToNearest(
              snapTo: [secondAnchor, maxAnchor],
            ),
          ),
        ),
        keyboardDismissBehavior: const SheetKeyboardDismissBehavior.onDrag(
          isContentScrollAware: false,
        ),
        child: Container(
          height: MediaQuery.of(context).size.height,
          clipBehavior: Clip.antiAlias,
          decoration: sheetShape,
          margin: const EdgeInsets.only(top: 8.0),
          child: SheetContentScaffold(
            extendBody: true,
            resizeToAvoidBottomInset: false,
            body: CalendarAddItemCreationView(
              focusNode: focusNode,
              firstDate: DateTime(0),
              lastDate: DateTime(9999),
              duration: const Duration(hours: 1).obs,
            ),
          ),
        ),
      ),
    );
  }
}
fujidaiti commented 7 months ago

Hi @Tommy-Wang0602.

Are you using the MobileCalendarAddItemBottomSheet inside a Scaffold? If so, that's the problem because the sheet and the SheetContentScaffold watch the MediaQueryData.viewInset.bottom to handle the appearing/disappearing of the keyboard, but the Scaffold consumes the viewInset resulting in the descendant widgets always getting viewInset.bottom == 0.

Here's the possible solutions for this case in my mind so far:

Stack(children: [ Scaffold(), YourSheet() ]);

Feel free to ask here if you have any question :)

appinteractive commented 7 months ago

@fujidaiti very valuable and important info, thanks!

Tommy-Wang0602 commented 7 months ago

Hi~ @fujidaiti
Thank you for your reply. I appreciate the practical advice and solution direction you provided, which resolved this issue.