flutter_sliding_box 1.1.5 copy "flutter_sliding_box: ^1.1.5" to clipboard
flutter_sliding_box: ^1.1.5 copied to clipboard

A draggable flutter widget (like bottom sheet panel) that makes it easier to use a SlidingBox for all platform.

example/lib/main.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sliding_box/flutter_sliding_box.dart';

void main() {
  runApp(const SlidingBoxExampleApp());
}

class SlidingBoxExampleApp extends StatelessWidget {
  const SlidingBoxExampleApp({super.key});

  static const ThemeMode themeMode = ThemeMode.light;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Flutter Sliding Box - Example App",
      theme: MyTheme.call(themeMode: themeMode),
      home: const SlidingBoxExamplePage(),
    );
  }
}

class SlidingBoxExamplePage extends StatefulWidget {
  const SlidingBoxExamplePage({super.key});

  @override
  State<SlidingBoxExamplePage> createState() => _SlidingBoxExamplePageState();
}

class _SlidingBoxExamplePageState extends State<SlidingBoxExamplePage> {
  final BoxController boxController = BoxController();
  final TextEditingController textEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();
    textEditingController.addListener(() {
      boxController.setSearchBody(
          child: Center(
        child: Text(
          textEditingController.text != ""
              ? textEditingController.value.text
              : "Empty",
          style: TextStyle(
              color: Theme.of(context).colorScheme.onBackground, fontSize: 20),
        ),
      ));
    });
  }

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

  @override
  Widget build(BuildContext context) {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      systemNavigationBarIconBrightness:
          SlidingBoxExampleApp.themeMode == ThemeMode.light
              ? Brightness.dark
              : Brightness.light,
      systemNavigationBarColor: Theme.of(context).colorScheme.background,
    ));
    //
    double bottomNavigationBarHeight =
        (MediaQuery.of(context).viewInsets.bottom > 0) ? 0 : 50;
    double appBarHeight = MediaQuery.of(context).size.height * 0.1;
    if (appBarHeight < 95) appBarHeight = 95;
    double minHeightBox =
        MediaQuery.of(context).size.height * 0.3 - bottomNavigationBarHeight;
    double maxHeightBox = MediaQuery.of(context).size.height -
        appBarHeight -
        bottomNavigationBarHeight;
    //
    return Scaffold(
      body: SlidingBox(
        controller: boxController,
        minHeight: minHeightBox,
        maxHeight: maxHeightBox,
        color: Theme.of(context).colorScheme.background,
        style: BoxStyle.sheet,
        backdrop: Backdrop(
          fading: true,
          overlay: false,
          color: Theme.of(context).colorScheme.secondary,
          body: _backdrop(),
          appBar: BackdropAppBar(
              title: Container(
                margin: const EdgeInsets.only(left: 15),
                child: Text(
                  "App Name",
                  style: TextStyle(
                    fontSize: 22,
                    color: Theme.of(context).colorScheme.onPrimary,
                  ),
                ),
              ),
              leading: Icon(
                Icons.menu,
                color: Theme.of(context).colorScheme.onPrimary,
                size: 30,
              ),
              searchBox: SearchBox(
                controller: textEditingController,
                color: Theme.of(context).colorScheme.background,
                style: TextStyle(
                    color: Theme.of(context).colorScheme.onBackground,
                    fontSize: 18),
                body: Center(
                  child: Text(
                    "Search Result",
                    style: TextStyle(
                        color: Theme.of(context).colorScheme.onBackground,
                        fontSize: 20),
                  ),
                ),
                draggableBody: true,
              ),
              actions: [
                Container(
                  margin: const EdgeInsets.fromLTRB(0, 0, 10, 0),
                  child: SizedBox.fromSize(
                    size: const Size.fromRadius(25),
                    child: IconButton(
                      iconSize: 27,
                      icon: Icon(
                        Icons.search_rounded,
                        color: Theme.of(context).colorScheme.onPrimary,
                      ),
                      onPressed: () {
                        textEditingController.text = "";
                        boxController.showSearchBox();
                      },
                    ),
                  ),
                ),
              ]),
        ),
        bodyBuilder: (sc, pos) => _body(sc, pos),
        collapsedBody: _collapsedBody(),
      ),
      bottomNavigationBar: BottomAppBar(
        padding: EdgeInsets.zero,
        height: bottomNavigationBarHeight,
        color: Theme.of(context).colorScheme.background,
        child: Container(
          decoration: BoxDecoration(
              color: Theme.of(context).colorScheme.background,
              border: Border(
                top: BorderSide(
                  width: 0.5,
                  color:
                      Theme.of(context).colorScheme.onBackground.withAlpha(100),
                ),
              )),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              IconButton(
                  onPressed: () {},
                  icon: Icon(
                    CupertinoIcons.chat_bubble_text,
                    color: Theme.of(context).colorScheme.onBackground,
                  )),
              IconButton(
                  onPressed: () {},
                  icon: Icon(
                    CupertinoIcons.phone,
                    color: Theme.of(context).colorScheme.onBackground,
                  )),
              IconButton(
                  onPressed: () {},
                  icon: Icon(
                    CupertinoIcons.plus_app,
                    color: Theme.of(context).colorScheme.onBackground,
                  )),
              IconButton(
                  onPressed: () {},
                  icon: Icon(
                    CupertinoIcons.photo_camera,
                    color: Theme.of(context).colorScheme.onBackground,
                  )),
              IconButton(
                  onPressed: () {},
                  icon: Icon(
                    CupertinoIcons.profile_circled,
                    color: Theme.of(context).colorScheme.onBackground,
                  )),
            ],
          ),
        ),
      ),
    );
  }

  _backdrop() {
    return Container(
      padding: const EdgeInsets.only(top: 60, bottom: 40),
      child: ListView(
        physics: const BouncingScrollPhysics(),
        children: [
          MaterialListItem(
              icon: const Icon(
                CupertinoIcons.house,
                size: 21,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Home",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.person_outline,
                size: 26,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Contacts",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                CupertinoIcons.camera,
                size: 22,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Camera",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.image_outlined,
                size: 24,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Album",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.person_add_alt_outlined,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Invite Friends",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.bookmark_border_rounded,
                size: 26,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Bookmarks",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.alarm,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Set Alarm",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                CupertinoIcons.person_2,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Add Group",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.contacts_outlined,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Contacts",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.video_camera_front_outlined,
                size: 26,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Video Call",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.add_location_alt_outlined,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Add Location",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.shopping_cart_outlined,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Checkout Cart",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.settings_outlined,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Settings",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
          MaterialListItem(
              icon: const Icon(
                Icons.help_outline,
                size: 25,
                color: Color(0xffeeeeee),
              ),
              child: const Text(
                "Helps",
                style: TextStyle(color: Color(0xffeeeeee), fontSize: 18),
              ),
              onPressed: () {}),
        ],
      ),
    );
  }

  _body(ScrollController sc, double pos) {
    sc.addListener(() {
      print("scrollController position: ${sc.position.pixels}");
    });
    return const Column(
      children: [
        SizedBox(
          height: 10,
        ),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
        MyListItem(),
      ],
    );
  }

  _collapsedBody() {
    return Center(
      child: Text(
        "Collapsed Body",
        style: TextStyle(
            fontWeight: FontWeight.normal,
            fontSize: 25,
            color: Theme.of(context).colorScheme.onBackground),
      ),
    );
  }
}

class MyListItem extends StatelessWidget {
  const MyListItem({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(10),
      padding: const EdgeInsets.all(10),
      height: 80,
      decoration: BoxDecoration(
        color: Theme.of(context).colorScheme.onBackground.withAlpha(40),
        borderRadius: const BorderRadius.all(Radius.circular(10)),
      ),
      child: Row(
        children: [
          Container(
            width: 60,
            height: 60,
            decoration: BoxDecoration(
              color: Theme.of(context).colorScheme.onBackground.withAlpha(60),
              borderRadius: const BorderRadius.all(Radius.circular(60)),
            ),
          ),
          Expanded(
              child: Column(
            children: [
              Container(
                margin: const EdgeInsets.only(left: 10, top: 5),
                height: 20,
                decoration: BoxDecoration(
                  color:
                      Theme.of(context).colorScheme.onBackground.withAlpha(60),
                  borderRadius: const BorderRadius.all(Radius.circular(7)),
                ),
              ),
              Container(
                margin: const EdgeInsets.only(left: 10, top: 9),
                height: 13,
                decoration: BoxDecoration(
                  color:
                      Theme.of(context).colorScheme.onBackground.withAlpha(40),
                  borderRadius: const BorderRadius.all(Radius.circular(7)),
                ),
              ),
            ],
          )),
        ],
      ),
    );
  }
}

class MaterialListItem extends StatelessWidget {
  final Icon? icon;
  final Widget child;
  final VoidCallback onPressed;

  const MaterialListItem(
      {super.key, this.icon, required this.child, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    double iconSizeHeight = 50;
    return SizedBox(
      height: iconSizeHeight,
      child: MaterialButton(
        padding: const EdgeInsets.all(0),
        minWidth: MediaQuery.of(context).size.height,
        splashColor: Colors.white.withAlpha(150),
        highlightColor: Colors.white.withAlpha(150),
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        onPressed: onPressed,
        child: Row(
          children: [
            if (icon != null)
              SizedBox(
                width: iconSizeHeight + 10,
                height: iconSizeHeight,
                child: icon,
              ),
            child,
          ],
        ),
      ),
    );
  }
}

class MyTheme {
  static call({required ThemeMode themeMode}) {
    if (themeMode == ThemeMode.light) {
      return ThemeData(
        useMaterial3: true,
        colorScheme: const ColorScheme(
          brightness: Brightness.light,
          background: Color(0xFFFFFFFF),
          onBackground: Color(0xFF222222),
          primary: Color(0xff607D8B),
          onPrimary: Color(0xFFFFFFFF),
          secondary: Color(0xff607D8B),
          onSecondary: Color(0xFFFFFFFF),
          error: Color(0xFFFF5252),
          onError: Color(0xFFFFFFFF),
          surface: Color(0xff607D8B),
          onSurface: Color(0xFFFFFFFF),
        ),
      );
    } else {
      return ThemeData(
        useMaterial3: true,
        colorScheme: const ColorScheme(
          brightness: Brightness.dark,
          background: Color(0xFF222222),
          onBackground: Color(0xFFEEEEEE),
          primary: Color(0xff324148),
          onPrimary: Color(0xFFEEEEEE),
          secondary: Color(0xff41555e),
          onSecondary: Color(0xff324148),
          error: Color(0xFFFF5252),
          onError: Color(0xFFEEEEEE),
          surface: Color(0xff324148),
          onSurface: Color(0xFFEEEEEE),
        ),
      );
    }
  }
}
90
likes
150
pub points
89%
popularity
screenshot

Publisher

verified publishershirvanie.ir

A draggable flutter widget (like bottom sheet panel) that makes it easier to use a SlidingBox for all platform.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_sliding_box