overscroll_feedback 0.0.3 copy "overscroll_feedback: ^0.0.3" to clipboard
overscroll_feedback: ^0.0.3 copied to clipboard

A Flutter ListView that reveals custom feedback when users pull beyond the scroll edge, with optional haptics and callbacks.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF2F6FED)),
        useMaterial3: true,
      ),
      home: const OverscrollFeedbackDemo(),
    );
  }
}

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

  @override
  State<OverscrollFeedbackDemo> createState() => _OverscrollFeedbackDemoState();
}

class _OverscrollFeedbackDemoState extends State<OverscrollFeedbackDemo> {
  int _reachCount = 0;

  static const _messages = [
    'Welcome aboard',
    'Pull gently',
    'Keep scrolling',
    'Nearly there',
    'Now pull past the end',
  ];

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

    return Scaffold(
      backgroundColor: colorScheme.surface,
      appBar: AppBar(title: const Text('OverscrollFeedback')),
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 12, 16, 4),
              child: Text(
                'Reach limit callbacks: $_reachCount',
                style: Theme.of(context).textTheme.titleMedium,
              ),
            ),
            Expanded(
              child: OverscrollFeedback.strings(
                position: OverscrollFeedbackPosition.both,
                messages: _messages,
                itemColor: colorScheme.primaryContainer,
                borderRadius: BorderRadius.circular(12),
                startReachLimitBuilder: (context, progress) {
                  return _LimitFeedback(
                    icon: Icons.arrow_upward_rounded,
                    label: 'Start of list',
                    progress: progress,
                    color: colorScheme.tertiaryContainer,
                    foregroundColor: colorScheme.onTertiaryContainer,
                  );
                },
                reachLimitBuilder: (context, progress) {
                  return _LimitFeedback(
                    icon: Icons.touch_app_rounded,
                    label: 'You reached the end',
                    progress: progress,
                    color: colorScheme.secondaryContainer,
                    foregroundColor: colorScheme.onSecondaryContainer,
                  );
                },
                onReachLimit: () {
                  setState(() {
                    _reachCount += 1;
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _LimitFeedback extends StatelessWidget {
  const _LimitFeedback({
    required this.icon,
    required this.label,
    required this.progress,
    required this.color,
    required this.foregroundColor,
  });

  final IconData icon;
  final String label;
  final double progress;
  final Color color;
  final Color foregroundColor;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Transform.scale(
        scale: 0.86 + (progress * 0.14),
        child: DecoratedBox(
          decoration: BoxDecoration(
            color: color,
            borderRadius: BorderRadius.circular(999),
          ),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 12),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(icon, size: 18, color: foregroundColor),
                const SizedBox(width: 8),
                Text(
                  label,
                  style: TextStyle(
                    color: foregroundColor,
                    fontWeight: FontWeight.w700,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
3
likes
0
points
306
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter ListView that reveals custom feedback when users pull beyond the scroll edge, with optional haptics and callbacks.

Repository (GitHub)
View/report issues

Topics

#flutter #listview #overscroll #scroll-effects #haptics

License

unknown (license)

Dependencies

flutter

More

Packages that depend on overscroll_feedback