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

Just another router, with a focus on ease of use and effective state management.

example/main.dart

import 'package:flutter/material.dart';

import 'package:df_router/df_router.dart';

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

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

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

  @override
  Widget build(BuildContext context) {
    return WidgetsApp(
      color: Colors.white,
      builder:
          (context, _) => RouteManager(
            fallbackRoute: '/home',
            transitionBuilder: (context, params) {
              // For iOS.
              return HorizontalSlideFadeTransition(
                prev: params.prev ?? const SizedBox.shrink(),
                controller: params.controller,
                duration: const Duration(milliseconds: 300),
                child: params.child,
              );
              // For Android.
              // return VerticalSlideFadeTransition(
              //   prev: params.prev ?? const SizedBox.shrink(),
              //   controller: params.controller,
              //   duration: const Duration(milliseconds: 300),
              //   child: params.child,
              // );
            },
            routes: [
              RouteBuilder(
                basePath: '/home',
                // Does not dispose the route when navigating away.
                shouldPreserve: false,
                // Animates the transition when navigating to this route.
                shouldAnimate: false,
                builder: (context, prev, pathQuery) {
                  return HomeScreen(pathQuery: pathQuery);
                },
              ),

              RouteBuilder(
                basePath: '/messages',
                shouldPreserve: true,
                shouldAnimate: true,
                builder: (context, prev, pathQuery) {
                  return MessagesScreen(pathQuery: pathQuery);
                },
              ),
              RouteBuilder(
                basePath: '/chat',
                shouldPreserve: false,
                // Builds the widget even if the route is not on the stack.
                shouldPrebuild: true,
                builder: (context, prev, pathQuery) {
                  return ChatScreen(pathQuery: pathQuery);
                },
              ),
              RouteBuilder(
                basePath: '/detail',
                shouldPreserve: false,
                builder: (context, prev, pathQuery) {
                  return HomeDetailScreen(pathQuery: pathQuery);
                },
              ),
            ],
          ),
    );
  }
}

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

class MessagesScreen extends StatefulWidget {
  final String pathQuery;

  const MessagesScreen({super.key, required this.pathQuery});

  @override
  State<MessagesScreen> createState() => _MessagesScreenState();
}

class _MessagesScreenState extends State<MessagesScreen> {
  int counter = 0;

  @override
  void initState() {
    super.initState();
    debugPrint('INIT STATE MESSAGES - Params: ${widget.pathQuery}');
  }

  @override
  void dispose() {
    debugPrint('MessagesScreen disposed - Params: ${widget.pathQuery}');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final controller = RouteController.of(context);
    return Container(
      color: Colors.lightGreen,
      child: Center(
        child: Column(
          spacing: 8.0,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(counter.toString()),
            FilledButton(
              onPressed: () => setState(() => counter++),
              child: const Text('Increment'),
            ),
            FilledButton(
              onPressed: () => controller.push('/home'),
              child: const Text('Go to Home'),
            ),
            FilledButton(
              onPressed: () => controller.push('/messages'),
              child: const Text('Go to Messages (No Query)'),
            ),
            FilledButton(
              onPressed: () => controller.push('/messages?key1=value1'),
              child: const Text('Go to Messages (key1=value1)'),
            ),
            FilledButton(
              onPressed: () => controller.disposeExactRoute('/messages?key1=value1'),
              child: const Text('DISPOSE Messages (key1=value1)'),
            ),
            FilledButton(
              onPressed: () => controller.push('/messages?key2=value2'),
              child: const Text('Go to Messages (key2=value2)'),
            ),
            FilledButton(
              onPressed: () => controller.disposeExactRoute(widget.pathQuery),
              child: const Text('Dispose This Route'),
            ),
          ],
        ),
      ),
    );
  }
}

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

class HomeScreen extends StatelessWidget {
  final String pathQuery;

  const HomeScreen({super.key, required this.pathQuery});

  @override
  Widget build(BuildContext context) {
    final controller = RouteController.of(context);
    debugPrint('INIT STATE HOME');
    return Container(
      color: Colors.yellow,
      child: Center(
        child: Column(
          spacing: 8.0,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FilledButton(
              onPressed: () => controller.push('/messages'),
              child: const Text('Go to Messages (No Query)'),
            ),
            FilledButton(
              onPressed: () => controller.push('/messages?key1=value1'),
              child: const Text('Go to Messages (key1=value1)'),
            ),
            FilledButton(
              onPressed: () => controller.push('/messages?key2=value2'),
              child: const Text('Go to Messages (key2=value2)'),
            ),
            FilledButton(
              onPressed: () => controller.push('/detail'),
              child: const Text('Go to Home Detail'),
            ),
            FilledButton(
              onPressed: () => controller.push('/chat'),
              child: const Text('Go to Chat'),
            ),
          ],
        ),
      ),
    );
  }
}

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

class ChatScreen extends StatefulWidget {
  final String pathQuery;

  const ChatScreen({super.key, required this.pathQuery});

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  @override
  void initState() {
    super.initState();
    debugPrint('INIT STATE CHAT - Params: ${widget.pathQuery}');
  }

  @override
  void dispose() {
    debugPrint('ChatScreen disposed - Params: ${widget.pathQuery}');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final controller = RouteController.of(context);
    return Container(
      color: Colors.blue,
      child: Center(
        child: Column(
          spacing: 8.0,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FilledButton(
              onPressed: () => controller.push('/home'),
              child: const Text('Go to Home'),
            ),
            FilledButton(
              onPressed: () => controller.push('/chat'),
              child: const Text('Go to Chat (No ID)'),
            ),
            FilledButton(
              onPressed: () => controller.push('/chat?id=123'),
              child: const Text('Go to Chat (ID=123)'),
            ),
            FilledButton(
              onPressed: () => controller.disposeExactRoute(widget.pathQuery),
              child: const Text('Dispose This Route'),
            ),
          ],
        ),
      ),
    );
  }
}

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

class HomeDetailScreen extends StatelessWidget {
  final String pathQuery;

  const HomeDetailScreen({super.key, required this.pathQuery});

  @override
  Widget build(BuildContext context) {
    final controller = RouteController.of(context);
    debugPrint('INIT STATE HOME DETAIL');
    return Container(
      color: Colors.green,
      child: Center(
        child: Column(
          spacing: 8.0,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FilledButton(
              onPressed: () => controller.push('/home'),
              child: const Text('Back to Home'),
            ),
            FilledButton(
              onPressed: () => controller.push('/messages'),
              child: const Text('Go to Messages'),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
0
points
102
downloads

Publisher

verified publisherdev-cetera.com

Weekly Downloads

Just another router, with a focus on ease of use and effective state management.

Repository (GitHub)
View/report issues

Topics

#router #navigation #state-management

Funding

Consider supporting this project:

www.buymeacoffee.com

License

unknown (license)

Dependencies

df_pwa_utils, flutter

More

Packages that depend on df_router