scroll_dismissible_page 0.1.0 copy "scroll_dismissible_page: ^0.1.0" to clipboard
scroll_dismissible_page: ^0.1.0 copied to clipboard

A Flutter page wrapper with scroll-aware swipe-down-to-dismiss. Nested scrollables keep working; dismiss only engages at the top edge.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:scroll_dismissible_page/scroll_dismissible_page.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'scroll_dismissible_page',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF1B4DFF),
          brightness: Brightness.light,
        ),
        useMaterial3: true,
        scaffoldBackgroundColor: const Color(0xFFF2F4F8),
      ),
      home: const DemoHomePage(),
    );
  }
}

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

  void _openDetail(BuildContext context) {
    Navigator.of(
      context,
    ).push(MaterialPageRoute<void>(builder: (_) => const DemoDetailPage()));
  }

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Scroll Dismissible Page'),
        centerTitle: false,
        backgroundColor: scheme.surface,
        surfaceTintColor: Colors.transparent,
      ),
      body: ListView(
        padding: const EdgeInsets.all(20),
        children: [
          Text(
            'Open a detail route, scroll normally, then swipe down from the '
            'top to dismiss.',
            style: Theme.of(
              context,
            ).textTheme.bodyLarge?.copyWith(color: scheme.onSurfaceVariant),
          ),
          const SizedBox(height: 24),
          FilledButton.icon(
            onPressed: () => _openDetail(context),
            icon: const Icon(Icons.open_in_full),
            label: const Text('Open gallery detail'),
          ),
        ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;

    return ScrollDismissiblePage(
      backgroundColor: Colors.black.withValues(alpha: 0.45),
      child: Scaffold(
        backgroundColor: scheme.surface,
        appBar: AppBar(
          title: const Text('Look detail'),
          backgroundColor: scheme.surface,
          surfaceTintColor: Colors.transparent,
        ),
        body: ListView.builder(
          padding: const EdgeInsets.fromLTRB(16, 8, 16, 32),
          itemCount: 24,
          itemBuilder: (context, index) {
            if (index == 0) {
              return Container(
                height: 220,
                margin: const EdgeInsets.only(bottom: 16),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [
                      scheme.primaryContainer,
                      scheme.secondaryContainer,
                    ],
                  ),
                ),
                alignment: Alignment.bottomLeft,
                padding: const EdgeInsets.all(20),
                child: Text(
                  'Swipe down to close',
                  style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                    fontWeight: FontWeight.w700,
                  ),
                ),
              );
            }

            return Card(
              margin: const EdgeInsets.only(bottom: 10),
              elevation: 0,
              color: scheme.surfaceContainerHighest.withValues(alpha: 0.55),
              child: ListTile(
                leading: CircleAvatar(
                  backgroundColor: scheme.primaryContainer,
                  child: Text('$index'),
                ),
                title: Text('Detail row $index'),
                subtitle: const Text('Scroll freely, then pull down at top'),
              ),
            );
          },
        ),
      ),
    );
  }
}
0
likes
160
points
70
downloads
screenshot

Documentation

API reference

Publisher

verified publisherayushd70.dev

Weekly Downloads

A Flutter page wrapper with scroll-aware swipe-down-to-dismiss. Nested scrollables keep working; dismiss only engages at the top edge.

Repository (GitHub)
View/report issues

Topics

#ui #dismiss #gesture #page #widget

License

MIT (license)

Dependencies

flutter

More

Packages that depend on scroll_dismissible_page