Home > other >  Flutter deepLinking navigate from initial screen(home screen) to next screen(college screen) after r
Flutter deepLinking navigate from initial screen(home screen) to next screen(college screen) after r

Time:04-29

dependencies using [get: ^4.3.4,uni_links: ^0.5.1]

main.dart build method :

@override   
Widget build(BuildContext context) {
    return MaterialApp.router(
      debugShowCheckedModeBanner: false,
      title: 'Navigator 2.0 Deep Link',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routerDelegate: routerDelegate,
      routeInformationParser: const MyRouteInformationParser(),
    );   
}

I have using routerDelegate and routeInformationParser for navigation...

Home screen onPress code :

          onPressed: () {
          return routerDelegate.pushPage(
            name: '/college',
            arguments: {
              "screenCode" : 7,
            }
          );
        },

below code how I have receiving param data from navigated file :

class College extends StatefulWidget {
   final Map<String,dynamic> arguments;
   const College({Key? key,required this.arguments}) : super(key: key);

  @override
  _CollegeState createState() => _CollegeState();
}

information_parser.dart file :

import 'package:flutter/material.dart';

class MyRouteInformationParser
    extends RouteInformationParser<List<RouteSettings>> {
  const MyRouteInformationParser() : super();

  @override
  Future<List<RouteSettings>> parseRouteInformation(
      RouteInformation routeInformation) {
    final uri = Uri.parse(routeInformation.location!);

    if (uri.pathSegments.isEmpty) {
      return Future.value([const RouteSettings(name: '/')]);
    }

    final routeSettings = uri.pathSegments
        .map((pathSegment) => RouteSettings(
              name: '/$pathSegment',
              arguments: pathSegment == uri.pathSegments.last
                  ? uri.queryParameters
                  : null,
            ))
        .toList();

    return Future.value(routeSettings);
  }

  @override
  RouteInformation restoreRouteInformation(List<RouteSettings> configuration) {
    final location = configuration.last.name;
    final arguments = _restoreArguments(configuration.last);

    return RouteInformation(location: '$location$arguments');
  }

  String _restoreArguments(RouteSettings routeSettings) {
    if(routeSettings.name == '/college') {
      return '?id=${(routeSettings.arguments as Map)['screenCode'].toString()}';
    } else {
      return '';
    }
  }
}

delegate.dart file :

import 'package:flutter/material.dart';
import 'package:nav_bar/ui/college.dart';
import 'package:nav_bar/ui/hostel.dart';
import 'package:nav_bar/ui/stadium.dart';
import '../router/transition_delegate.dart';
import '../ui/home.dart';

class MyRouterDelegate extends RouterDelegate<List<RouteSettings>>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<List<RouteSettings>> {
  final _pages = <Page>[];

  @override
  final navigatorKey = GlobalKey<NavigatorState>();

  @override
  List<Page> get currentConfiguration => List.of(_pages);

  @override
  Widget build(BuildContext context) {
    return Navigator(
        key: navigatorKey,
        pages: List.of(_pages),
        onPopPage: _onPopPage,
        transitionDelegate: const MyTransitionDelegate());
  }

  @override
  Future<bool> popRoute() {
    if (_pages.length > 1) {
      _pages.removeLast();
      notifyListeners();
      return Future.value(true);
    }

    return _confirmAppExit();
  }

  @override
  Future<void> setNewRoutePath(List<RouteSettings> configuration) {
    _setPath(configuration
        .map((routeSettings) => _createPage(routeSettings))
        .toList());
    return Future.value(null);
  }

  void parseRoute(Uri uri) {
    if (uri.pathSegments.isEmpty) {
      setNewRoutePath([const RouteSettings(name: '/')]);
    } else {
      setNewRoutePath(uri.pathSegments
          .map((pathSegment) => RouteSettings(
                name: '/$pathSegment',
                arguments: pathSegment == uri.pathSegments.last
                    ? uri.queryParameters
                    : null,
              ))
          .toList());
    }
  }

  bool _onPopPage(Route route, dynamic result) {
    if (!route.didPop(result)) return false;

    popRoute();
    return true;
  }

  void _setPath(List<Page> pages) {
    _pages.clear();
    _pages.addAll(pages);

    if (_pages.first.name != '/') {
      _pages.insert(0, _createPage(const RouteSettings(name: '/')));
    }
    notifyListeners();
  }

  void pushPage({required String name, dynamic arguments}) {
    _pages.add(_createPage(RouteSettings(name: name, arguments: arguments)));
    notifyListeners();
  }

  MaterialPage _createPage(RouteSettings routeSettings) {
    Widget child;

    switch (routeSettings.name) {
      case '/':
        child = const HomePage();
        break;
      case '/college':
        child = College(arguments: routeSettings.arguments as Map<String,dynamic>);
        break;
      case '/hostel':
        child = Hostel();
        break;
      case '/stadium':
        child = Stadium();
        break;
      default:
        child = Scaffold(
          appBar: AppBar(title: const Text('404')),
          body: const Center(child: Text('Page not found')),
        );
    }

    return MaterialPage(
      child: child,
      key: Key(routeSettings.toString()) as LocalKey,
      name: routeSettings.name,
      arguments: routeSettings.arguments,
    );
  }

  Future<bool> _confirmAppExit() async {
    final result = await showDialog<bool>(
        context: navigatorKey!.currentContext!,
        builder: (context) {
          return AlertDialog(
            title: const Text('Exit App'),
            content: const Text('Are you sure you want to exit the app?'),
            actions: [
              TextButton(
                child: const Text('Cancel'),
                onPressed: () => Navigator.pop(context, true),
              ),
              TextButton(
                child: const Text('Confirm'),
                onPressed: () => Navigator.pop(context, false),
              ),
            ],
          );
        });

    return result ?? true;
  }
}

After navigation my url will be http://localhost:56127/#/college?id=7

my issue is after refresh that screen param data have changed to null like below

http://localhost:56127/#/college?id=null

Please revert how to resolve?

CodePudding user response:

Use Hive or secure storage to save your params locally. It won't get lost after refresh. Just read the saved params when you need it.

CodePudding user response:

Issue fixed :

I have done small mistake

onPressed: () {
          return routerDelegate.pushPage(
            name: '/college',
            arguments: {
              "screenCode" : 7,
            }
          );
        },
if(routeSettings.name == '/college') {
      return '?id=${(routeSettings.arguments as Map)['screenCode'].toString()}';
    }

in onPressed function I declare key name as screenCode. but in routeSettings query Param I have declared as id.....so changed id to screenCode... fixed

  • Related