A Flutter slidable widget that provides an easy to use configuration. Highly customisable. Just as you want it!

Overview

sliding_panel

The most customisable bottom sliding panel you can find on pub.dev. Just as you want it!


Features you would love

Demo



Take control Customize the way you want Various purposes
Screenshot Screenshot Screenshot

Easily put your content in the panel, customize it and then just use the panel for various purposes like,

  • Showing some persistent content on bottom of the screen.
  • Can be used like showModalBottomSheet() from Flutter to make user choices.
  • Also use like DraggableScrollableSheet() and put scrollable content inside the panel.

👉 How to use sliding_panel:

Please visit the Wiki to see how you can get this working.

👌 Liked my work?

You can always hit the 👍 button and it.

Still not enough??? paypal.me.


Users of v0.5.0 and 0.7.0:

The latest stable release (v1.0.1) has landed with many improvements. There are some breaking changes, too. For that, visit the Migration guide.


A note for v0.2.0 and v0.1.0 users 😟

From version 0.5.0, we have a LOADS of breaking 💥 changes, which means that simply updating the package won't give you all the bells and whistles of new version. 😔 For updating guide, please go to the Migration guide.

  • After following this guide, you will enjoy new features.
Comments
  • Back btn close parent

    Back btn close parent

    Hi, Thanks for a lot of grate work! One think which is blocker for me to use your lib is behaviour of back btn. It close not only panel but also page which launch it. You can see this behaviour in your 'Modal panel' example. Steps: 1 ) Open Modal Panel Page 2) Press Open the panel btn 3) press Android back btn. Expected behaviour: Panel should close Actual behaviour: Panel is close as well as 'Modal Panel' Page

    opened by ghost 16
  • When not providing a bodyContent to a modal SlidingSheet there is no shadow for the content behind the sheet

    When not providing a bodyContent to a modal SlidingSheet there is no shadow for the content behind the sheet

    Code:

      /// Show bottom panel
      void showPanel() async {
        final panel = await showModalSlidingPanel(
          context: context,
          panel: (context) => SlidingPanel(
            panelController: _panelController,
            snapping: PanelSnapping.enabled,
            isDraggable: true,
            backPressBehavior: BackPressBehavior.POP,
            isTwoStatePanel: true,
            size: PanelSize(
              closedHeight: 0.5,
              expandedHeight: 1.0,
            ),
            backdropConfig: BackdropConfig(
              enabled: true,
              dragFromBody: true,
            ),
            content: PanelContent(
              headerWidget: PanelHeaderWidget(
                decoration: PanelDecoration(
                  backgroundColor: Colors.grey[800]
                ),
                options: PanelHeaderOptions(
                  primary: false,
                ),
                headerContent: Padding(
                  padding: const EdgeInsets.all(6),
                  child: Material(
                    elevation: 4,
                    child: TextField(
                      onTap: () => _panelController.expand(),
                      decoration: InputDecoration(
                        filled: true,
                        fillColor: Theme.of(context).canvasColor,
                        border: InputBorder.none,
                        prefixIcon: Icon(Icons.search, color: Colors.white),
                        suffixIcon: Icon(Icons.more_vert, color: Colors.white),
                        hintText: 'Instance Search...'
                      ),
                    ),
                  ),
                ),
              ),
              panelContent: [
                ...
              ],
            ),
          ),
        );
      }
    

    Screenshot: image

    fixed 
    opened by GroovinChip 11
  • Androidx migration

    Androidx migration

    Currently, it is recommended that Apps and libraries uses AndroidX instead of Android Support Library. Every new Flutter project will be created as and AndroidX project, and it may be a problem to build AndroidX and Android Support Library together (it is indeed the case with my project, for example).

    This document describes how to migrate a flutter project to use AndroidX. https://flutter.dev/docs/development/androidx-migration

    opened by gabrielgarciagava 5
  • snapPanel only works sometimes

    snapPanel only works sometimes

    Is there a way to always make the panel snap to closed, collapsed, and expanded states? i want the slightest drag, for the panel to snap in the direction of the drag. currently with snapPanel set to true, its only snapping to expanded when i do a quick drag. I'm using a simulator btw.

    opened by fremfi 5
  • Disposing Controller crashing the app on Navigator Pop

    Disposing Controller crashing the app on Navigator Pop

    when Sliding Panel showed up, this exception happens

    ════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
    The following assertion was thrown while finalizing the widget tree:
    ScrollableState#ca85e(tickers: tracking 1 ticker, position: _PanelScrollPosition#c9215(offset: 0.0, range: 0.0..1.0, viewport: 77.0, ScrollableState, ClampingScrollPhysics, null, ScrollDirection.idle)) was disposed with an active Ticker.
    
    ScrollableState created a Ticker via its TickerProviderStateMixin, but at the time dispose() was called on the mixin, that Ticker was still active. All Tickers must be disposed before calling super.dispose(). Tickers used by AnimationControllers should be disposed by calling dispose() on the AnimationController itself. Otherwise, the ticker will leak.
    The offending ticker was: _WidgetTicker(created by ScrollableState#ca85e(tickers: tracking 0 tickers, position: _PanelScrollPosition#c9215(offset: 0.0, range: 0.0..1.0, viewport: 77.0, ScrollableState, ClampingScrollPhysics, IdleScrollActivity#443f8, ScrollDirection.idle)))
    The stack trace when the _WidgetTicker was actually created was:
    #0      new Ticker.<anonymous closure> (package:flutter/src/scheduler/ticker.dart:64:40)
    #1      new Ticker (package:flutter/src/scheduler/ticker.dart:66:6)
    #2      new _WidgetTicker (package:flutter/src/widgets/ticker_provider.dart:225:80)
    #3      TickerProviderStateMixin.createTicker (package:flutter/src/widgets/ticker_provider.dart:161:34)
    #4      new AnimationController (package:flutter/src/animation/animation_controller.dart:245:21)
    #5      _setPanelPosition (package:sliding_panel/src/utils.dart:260:33)
    <asynchronous suspension>
    #6      PanelController.collapse (package:sliding_panel/src/controller.dart:107:13)
    <asynchronous suspension>
    #7      _OrderPageState.buildGoogleMap.<anonymous closure> (package:sg_mobile/ui/order/order_page.dart:91:26)
    #8      _GoogleMapState.onPlatformViewCreated (package:google_maps_flutter/src/google_map.dart:296:14)
    <asynchronous suspension>
    #9      AndroidViewController._create (package:flutter/src/services/platform_views.dart:643:15)
    <asynchronous suspension>
    #10     AndroidViewController.setSize (package:flutter/src/services/platform_views.dart:557:14)
    <asynchronous suspension>
    #11     RenderAndroidView._sizePlatformView (package:flutter/src/rendering/platform_view.dart:174:29)
    <asynchronous suspension>
    #12     RenderAndroidView.performResize (package:flutter/src/rendering/platform_view.dart:155:5)
    #13     RenderObject.layout (package:flutter/src/rendering/object.dart:1686:9)
    #14     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
    #15     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #16     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:549:15)
    #17     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #18     _RenderLayoutBuilder.performLayout (package:flutter/src/widgets/layout_builder.dart:242:13)
    #19     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #20     RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:206:11)
    #21     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #22     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:142:11)
    #23     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:444:7)
    #24     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
    #25     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
    #26     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #27     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #28     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #29     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #30     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1232:11)
    #31     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #32     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #33     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #34     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #35     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #36     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #37     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #38     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #39     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #40     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #41     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #42     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #43     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #44     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
    #45     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #46     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3138:14)
    #47     RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
    #48     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
    #49     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1578:7)
    #50     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:844:18)
    #51     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:341:19)
    #52     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:761:13)
    #53     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:280:5)
    #54     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1033:15)
    #55     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:975:9)
    #56     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:891:5)
    #60     _invoke (dart:ui/hooks.dart:249:10)
    #61     _drawFrame (dart:ui/hooks.dart:207:3)
    (elided 3 frames from package dart:async)
    
    When the exception was thrown, this was the stack: 
    #0      TickerProviderStateMixin.dispose.<anonymous closure> (package:flutter/src/widgets/ticker_provider.dart:178:13)
    #1      TickerProviderStateMixin.dispose (package:flutter/src/widgets/ticker_provider.dart:191:6)
    #2      ScrollableState.dispose (package:flutter/src/widgets/scrollable.dart:370:11)
    #3      StatefulElement.unmount (package:flutter/src/widgets/framework.dart:4142:12)
    #4      _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1738:13)
    ...
    

    when a page got disposed by Back button, i got this

    ════════ (2) Exception caught by widgets library ═══════════════════════════════════════════════════
    'package:flutter/src/widgets/framework.dart': Failed assertion: line 1773 pos 12: '_elements.contains(element)': is not true.
    User-created ancestor of the error-causing widget was: 
      ScrollConfiguration file:///C:/Project%20Android%20Studio/Starguard/sg_mobile/lib/app.dart:14:18
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    
    ════════ (3) Exception caught by widgets library ═══════════════════════════════════════════════════
    'package:flutter/src/widgets/framework.dart': Failed assertion: line 1773 pos 12: '_elements.contains(element)': is not true.
    User-created ancestor of the error-causing widget was: 
      ScrollConfiguration file:///C:/Project%20Android%20Studio/Starguard/sg_mobile/lib/app.dart:14:18
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    
    ════════ (4) Exception caught by widgets library ═══════════════════════════════════════════════════
    The getter 'userGestureInProgress' was called on null.
    Receiver: null
    Tried calling: userGestureInProgress
    User-created ancestor of the error-causing widget was: 
      ScrollConfiguration file:///C:/Project%20Android%20Studio/Starguard/sg_mobile/lib/app.dart:14:18
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    

    Strangely that only happened in Debug build, either they hid it on Release build or something wrong with AnimationController not getting disposed

    ignored 
    opened by alvinvin00 5
  • Add Scroll Physics option

    Add Scroll Physics option

    Hi,

    This simple PR allows users to configure custom ScrollPhysics behavior. If null, the panel will work just like before (defaults to platform convention).

    The documentation is inspired by ListView's physics documentation; physics → ScrollPhysics How the scroll view should respond to user input. [...]

    Tested several physics on Android:

    • BouncingScrollPhysics works properly;
    • NeverScrollableScrollPhysics basically disables dragging.
    opened by FilipeLarga 4
  • Wrong closedHeight when removing header

    Wrong closedHeight when removing header

    Hi, This strange behavior happens when transitioning from using headerSizeIsClosed with a PanelHeaderWidget to no PanelHeaderWidget at all.

    To make the transition I'm using

    setState(() {
      _headerWidget = null;
      pc.rebuild(then: () => pc.expand());
      }),
    

    Here is a video demonstrating the issue.

    1. Please note the initial panel closed size (very small, intended behavior).
    2. After transitioning to using a header, the panel closed size becomes the size of the header (intended behavior).
    3. After removing the header and going back to the initial mode, the panel closed size does not go back to what it should be, but instead remains the size of the header.

    Imgur Video Link

    The issue demonstrated in this video is that in the end, the panel does not go as low as it did in the beginning, despite both not having a header. If the video is unclear, please try lowering the panel after swapping modes with the sample code that replicates the screen:

    class GithubExample extends StatefulWidget {
      const GithubExample();
      @override
      _GithubExampleState createState() => _GithubExampleState();
    }
    
    class _GithubExampleState extends State<GithubExample> {
      PanelController pc;
      Widget _headerWidget;
      String _mode;
    
      @override
      void initState() {
        super.initState();
        pc = PanelController();
        _mode = 'No Header';
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Dynamic Panel Content'),
          ),
          body: Stack(
            children: <Widget>[
              Center(child: Text('Background')),
              SlidingPanel(
                panelController: pc,
                backdropConfig: BackdropConfig(
                    enabled: true, closeOnTap: true, shadowColor: Colors.blue),
                content: PanelContent(
                    panelContent: [
                      Container(
                        height: 200,
                        color: Colors.lightGreen,
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            Text('MODE: ' + _mode),
                            Row(
                              children: <Widget>[
                                MaterialButton(
                                  onPressed: () => setState(() {
                                    _headerWidget = null;
                                    _mode = 'No Header';
                                    pc.rebuild(then: () => pc.expand());
                                  }),
                                  child: Text('No header'),
                                ),
                                MaterialButton(
                                  onPressed: () => setState(() {
                                    _headerWidget = _headerSmall();
                                    _mode = 'Small Header';
                                    pc.rebuild(then: () => pc.expand());
                                  }),
                                  child: Text('Small header'),
                                ),
                                MaterialButton(
                                  onPressed: () => setState(() {
                                    _headerWidget = _headerBig();
                                    _mode = 'Big Header';
                                    pc.rebuild(then: () => pc.expand());
                                  }),
                                  child: Text('Big header'),
                                )
                              ],
                            ),
                          ],
                        ),
                      )
                    ],
                    headerWidget: _headerWidget != null
                        ? PanelHeaderWidget(
                            options: PanelHeaderOptions(elevation: 0),
                            headerContent: _headerWidget)
                        : const PanelHeaderWidget()),
                snapping: PanelSnapping.forced,
                size: PanelSize(closedHeight: 0.06, expandedHeight: 0.85),
                autoSizing: PanelAutoSizing(
                  autoSizeExpanded: true,
                  headerSizeIsClosed: true,
                  useMinExpanded: true,
                ),
                isTwoStatePanel: true,
                duration: Duration(milliseconds: 500),
              ),
            ],
          ),
        );
      }
    
      Widget _headerSmall() {
        return Container(
          color: Colors.lightBlue,
          child: Center(child: Text('SMALL HEADER')),
          height: 60,
          width: double.infinity,
        );
      }
    
      Widget _headerBig() {
        return Container(
          color: Colors.lightBlue,
          child: Center(child: Text('BIG HEADER')),
          height: 120,
          width: double.infinity,
        );
      }
    }
    
    bug fixed 
    opened by FilipeLarga 3
  • The panel content doesn't response to onTap event after drag to expand

    The panel content doesn't response to onTap event after drag to expand

    Hi, RaviKavaiya The panel content doesn't respond to the first onTap event after drag closed to expanded. Once u scroll the list or tap again it triggers.

    import 'package:flutter/material.dart';
    import 'package:sliding_panel/sliding_panel.dart';
    
    class TestWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return SlidingPanel(
                        panelController: PanelController(),
                        initialState: InitialPanelState.closed,
                        size: PanelSize(expandedHeight: 0.85),
                        autoSizing: PanelAutoSizing(headerSizeIsClosed: true),
                        duration: const Duration(milliseconds: 300),
                        backdropConfig: BackdropConfig(enabled: false),
                        decoration: PanelDecoration(
                            backgroundColor: Colors.white,
                            borderRadius: const BorderRadius.only(
                                topLeft: Radius.circular(8),
                                topRight: Radius.circular(8))),
                        backPressBehavior: BackPressBehavior.COLLAPSE_POP,
                        content: PanelContent(
                          panelContent: _buildChildList(),
                          headerWidget: PanelHeaderWidget(
                            headerContent: Container(
                              height: 100,
                              color: Colors.green,
                            ),
                            decoration: PanelDecoration(
                                backgroundColor: Colors.white,
                                borderRadius: const BorderRadius.only(
                                    topLeft: Radius.circular(8),
                                    topRight: Radius.circular(8))),
                          ),
                        ));
      }
    
      List<Widget> _buildChildList() {
        List<Widget> list = List();
        for (int i = 0; i < 100; i++) {
          list.add(GestureDetector(
            onTap: () {
              print('click $i');
            },
            child: Container(
              height: 70,
              child: Text('$i'),
            ),
          ));
        }
        return list;
      }
      
      
    }
    
    bug fixed 
    opened by Warpath 3
  • Is it possible to make it so the leading space of a PanelHeaderWidget is not used?

    Is it possible to make it so the leading space of a PanelHeaderWidget is not used?

    Currently, even without a specified leading widget, there is space allocated for it on the PanelHeaderWidget. I am not able to get the headerContent to take up the whole width of the PanelHeaderWidget.

    Code:

      /// Show bottom panel
      void showPanel() async {
        final panel = await showModalSlidingPanel(
          context: context,
          panel: (context) => SlidingPanel(
            panelController: _panelController,
            snapping: PanelSnapping.enabled,
            isDraggable: true,
            backPressBehavior: BackPressBehavior.POP,
            isTwoStatePanel: true,
            size: PanelSize(
              closedHeight: 0.5,
              expandedHeight: 1.0,
            ),
            backdropConfig: BackdropConfig(
              enabled: true,
              dragFromBody: true,
            ),
            content: PanelContent(
              headerWidget: PanelHeaderWidget(
                decoration: PanelDecoration(
                  backgroundColor: Colors.grey[800]
                ),
                options: PanelHeaderOptions(
                  primary: false,
                ),
                headerContent: Padding(
                  padding: const EdgeInsets.all(6),
                  child: Material(
                    elevation: 4,
                    child: TextField(
                      onTap: () => _panelController.expand(),
                      decoration: InputDecoration(
                        filled: true,
                        fillColor: Theme.of(context).canvasColor,
                        border: InputBorder.none,
                        prefixIcon: Icon(Icons.search, color: Colors.white),
                        suffixIcon: Icon(Icons.more_vert, color: Colors.white),
                        hintText: 'Instance Search...'
                      ),
                    ),
                  ),
                ),
              ),
              panelContent: [
                ...
              ],
            ),
          ),
        );
      }
    

    Screenshot: image

    opened by GroovinChip 3
  • setState called after dispose() SlidingPanel

    setState called after dispose() SlidingPanel

    I have a TextFieldController in my app, but everytime I type anything in it using my keyboard my entire app reloads and shows me the error,

    Error: setState() called after dispose(): _SlidingPanelState#65b14(lifecycle state: defunct, not mounted)

    The error seems related to [SlidingPanel][1] but I'm not sure why is it interfering with TextFieldController.

    SliverToBoxAdapter(
                       child: Container(
                         height: 100,
                         padding: const EdgeInsets.all(20.0),
                         child: TextField(
                           decoration: InputDecoration(
                               border: InputBorder.none,
                               labelText: 'Enter Name',
                               hintText: 'Enter Your Name'),
                         ),
                       ),
                     ),
    
    invalid 
    opened by anavrinapps 2
  • fixed collapsed height?

    fixed collapsed height?

    hi there, cant seem to figure out how to set a min/fixed height.

    PanelSize(closedHeight: 0.02, expandedHeight: 0.9),
    

    this seems only option but its percentage. i am trying to have say 40 px content area shown. is it possible?

    opened by hampsterx 2
  • Sliding panel reluctant to open, instead scrolling within a peek, Scroll controller not attaching for manipulation

    Sliding panel reluctant to open, instead scrolling within a peek, Scroll controller not attaching for manipulation

    ScrollController difficulty.

    When the user selects a location from the drawer, I've created a peek, using minHeight: on the sliding up panel, which the user can fling up for more information.

    Screenshot_1622112004

    If the user navigates down the sliding panel, to say the bottom

    Screenshot_1622112014

    Then goes to the drawer to view a new location, say item: "Arthur's Seat" here:

    Screenshot_1622112031

    Well tapping that triggers slidingPanelController.close();

    And then the sliding panel is once more called with

        setState(() {
          panelMinHeight = teaserPanelHeight;
        });
    
    

    Thereby opening a Panel peek at the new location, but it doesn't reveal the top content of the sliding panel, the Location's title, but in fact a slither of the panel midway down.

    If the user tries to pull the panel up gently, it just starts scrolling the panel in the peek's 177px window. They have to really effortfully fling it to enlarge the panel so they can read it easily.

    It's a bad user experience.

    I'm attaching a ScrollController to the SlidingPanel's ListView as per the examples:

      Widget _scrollingList(ScrollController slideUpPanelScrollController, LocationDetails presentLocation) {
        return ListView(
            controller: slideUpPanelScrollController,
            key: Key("scrollingPanelListView"),
            children: [Text("nothing here")]
    );
    

    I assume that attached it, however if, on choosing a new location from the drawer, I try to use slideUpPanelScrollController.jumpTo(0);

    Android Studio complains:

    ScrollController not attached to any scroll views.
    'package:flutter/src/widgets/scroll_controller.dart':
    Failed assertion: line 171 pos 12: '_positions.isNotEmpty'
    

    Screenshot_1622112075

    Sliding Panels must primarily be used for Maps, giving peeks you pull up, like I've tried to implement, it's the Google Maps paradigm.

    1. It would be great to have an easy way to reset the panel's ScrollPosition, so when the panel is loaded with fresh data the Panel starts at the top. Have it like a boolean property of the panel - reset Scroll with new data, or something.
    2. It would be great to prevent Scrolling of the Sliding Panel until it's been pulled open and reached its maxHeight.
    3. Or it would be great to have documentation on how to do this as is.
    opened by Sam-Guru-In-Training 0
  • Null-safety support

    Null-safety support

    First of all, thanks a lot for this package.

    I have been in the process of migrating my app to dart 2.12.x-pre to get some basic null safety checks going. It would be nice if this package had a null safe version too. See https://dart.dev/null-safety/migration-guide

    opened by ErliSoares 2
  • Apply footer shadow on scroll

    Apply footer shadow on scroll

    It looks like there's no way to apply elevation shadows to the footer on scroll. It would be ideal to be able to control this behavior similar to the header.

    opened by chimon2000 0
Owner
Ravi Kavaiya
A noob 😒
Ravi Kavaiya
A highly customisable and simple widget for having iOS 13 style tab bars.

cupertino_tabbar A highly customisable and simple widget for having iOS 13 style tab bars. It is highly recommended to read the documentation and run

AliYigitBireroglu 98 Oct 31, 2022
It's a universal app template to have a great animated splash screen and liquid slider. Just change the animation if you want (rive) and change the images or colours according to your app.

liquid A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this i

Zikyan Rasheed 28 Oct 7, 2022
This package adds CustomRefreshIndicator widget that allows you to create whatever indicator you want.

Custom Refresh Indicator A flutter package that allows you to easily create a custom refresh indicator widget. TLDR; ONLINE DEMO! QUICK START CustomRe

Kamil Klyta 315 Dec 16, 2022
A package that provides a highly customizable sheet widget that snaps to different vertical & horizontal positions

Snapping Sheet A package that provides a highly customizable sheet widget that snaps to different vertical & horizontal positions Can adapt to scrolla

Adam Jonsson 364 Dec 6, 2022
⚡️A highly customizable, powerful and easy-to-use alerting library for Flutter.

Flash ⚡️ A highly customizable, powerful and easy-to-use alerting library for Flutter. Website: https://sososdk.github.io/flash Specs This library all

null 368 Jan 5, 2023
A carousel package in flutter with various configuration options

Flutter_Carosel A simple Carousel Widget with multiple configuration option. ... dependencies: ... flutter_multi_carousel: ^1.0.0 ... And install it

GeekyAnts 67 Oct 2, 2022
Create flutter project with all needed configuration in two minutes (theme, localization, connect to firebase, FCM, local notifications, safe API call, error handling, animation..etc)

Flutter GetX Template Flutter Getx template to make starting project fast and easy . Introduction We all face the same problem when we want to start a

Emad Beltaje 150 Jan 7, 2023
The EasyRichText widget provides an easy way to use RichText.

easy_rich_text The EasyRichText widget makes the RichText widget easy. You do not have to split the string manually. This widget use regular expressio

hans.huang 55 Jan 4, 2023
A flutter widget to indicate loading progress. Easy to use, easy to extend

?? ?? ?? A flutter widget to indicate loading progress. Easy to use, easy to extend

Manuel Duarte 2 May 30, 2022
A customisable height slider for Flutter.

Height Slider Widget for Flutter ✨ Demo ?? Usage class _MyHomePageState extends State<MyHomePage> { int height = 170; @override Widget build(Bu

Coval Solutions 15 Aug 21, 2021
Clean, beautiful and customisable calendar package for flutter

Word from creator Hello ?? , Yeah I know Clean calendar is still very new, but don't be put off by it because it will be well-maintained for a very, v

Deepanshu Chaudhary 8 Dec 15, 2022
Custom dropdown widget allows to add highly customizable widget in your projects with proper open and close animations and also comes with form required validation.

Custom Dropdown Custom Dropdown package lets you add customizable animated dropdown widget. Features Lots of properties to use and customize dropdown

Abdullah Chauhan 22 Dec 29, 2022
A TabBarController that is easy to use for flutter developers. 🥰 It supports various styles of page navigation, and you can also use it to customize your favorite styles. 🍻🍻

easy_tab_controller A user-friendly TabBarController widget for flutter developer. Getting Started This project is a starting point for a Flutter plug

圆号本昊 3 May 26, 2022
Add beautiful animated effects & builders in Flutter, via an easy, highly customizable unified API.

Flutter Animate A performant library that makes it simple to add almost any kind of animated effect in Flutter. Pre-built effects, like fade, scale, s

Grant Skinner 352 Dec 25, 2022
This is a Flutter Food Recipe App this shows food recipes of any food which you want.

food_recipe_app A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started

Saksham gupta 3 Oct 31, 2022
Ever want to create a quick form without wiring everything up? This might be the library for you.

Ever want to create a quick form without wiring everything up? This might be the library for you.

Adam Hammer 15 Sep 13, 2022
This library provides a customizable Flutter widget that makes it easy to display text in the middle of a Divider.

1. About 1.1. Introduction 1.1.1. Install Library 1.1.2. Import It 1.1.3. Use TextDivider 1.2. Details 1.2.1. Customization Options 1.2.2. Horizontal

Kato Shinya 2 Feb 9, 2022