Home Blog Page 16

Exploring the Power of Flutter InAppWebView

0
flutter in app webview

Hi Guy’s Welcome to Proto Coders Point.

Are you looking for a easiest way to integrate InApp WebView in Futter app? Now need to research anymore! In this Flutter Article blog, we will be exploring Flutter InAppWebView. From understanding what web views and headless web views are.

Flutter is booming now a days as it has revolutionized the way that the developers are create mobile applications as well as web, desktop using flutter frameware that too with its fast development times and excellent performance capabilities. Flutter framework has the ability to integrate webviews seamlessly into the Flutter application. Flutter_InAppWebView is a powerful package using which a flutter developer can create highly interactive and responsive web-embedded apps to show external third party website pages into flutter app itself.


What is webview in Flutter?

Support you are building a Flutter Application, and want to show a external website page into the app for this you can make use of Flutter Webview. Basically a Web View allows a developers to embed a web page into a mobile application.

What is headless WebView?

A Headless WebView, is basically a Webview that don’t display any content from the web page. Instead the website/web page content get’s loaded at background and the developers can use it to get data from the website and use it for building flutter app. This headless Webview is now a days used for web-based API’s.

Adding the InAppWebView Widget into your Flutter App

Integrating InAppWebView widget into your Flutter app is much easy then you think. Now with just a few lines of code, You can build a awesome web-embedded Flutter Application where you can load you website into flutter app.

Integrating InApp Webview in Flutter App – Example

To Add InApp Webview into flutter app we will make use of flutter_inappwebview library, This flutter package will help you to open an in-app browser window.

InAppWebView Widget Syntax

InAppWebView(
                initialUrlRequest: URLRequest(
                  url: Uri.parse("https://protocoderspoint.com/")
                ),
                onWebViewCreated: (InAppWebViewController controller){
                  inAppWebViewController = controller;
                },
                onProgressChanged: (InAppWebViewController controller , int progress){
                  setState(() {
                    _progress = progress / 100;
                  });
                },
  ),

In InAppWebView widget there are various properties though which you can customize WebView in Flutter, Out of all those i have make used of:

initialUrlRequest: used to load a website or web page through URL.

onWebViewCreated(): This property is used to take control to the webview, Using this the flutter developer can attach a InAppWebViewController so that developer can create a controller for the webview and handle it.

onProgressChanged(): This function is been used to get the progress of how much percentage the website is loaded.


Complete Source Code Example – Flutter InAppWebView

In Below Code I have make used of a Stack Widget so that I can show a Webview and a progress indicator, Through Progress Indicator the app user can understand how much percentage of webview is loaded.

To handle webview to navigate to previous page that the user has open in the webview, I am using WillPopScope Widget to check on backpress is the webview can go back, if it can go back then go back one step to previous Web Page within the WebView.

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

class MyWebsite extends StatefulWidget {
  const MyWebsite({Key? key}) : super(key: key);

  @override
  State<MyWebsite> createState() => _MyWebsiteState();
}

class _MyWebsiteState extends State<MyWebsite> {

  double _progress = 0;
  late InAppWebViewController  inAppWebViewController;

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: ()async{

        var isLastPage = await inAppWebViewController.canGoBack();

        if(isLastPage){
          inAppWebViewController.goBack();
          return false;
        }

        return true;
      },
      child: SafeArea(
        child: Scaffold(
          body: Stack(
            children: [
              InAppWebView(
                initialUrlRequest: URLRequest(
                  url: Uri.parse("https://protocoderspoint.com/")
                ),
                onWebViewCreated: (InAppWebViewController controller){
                  inAppWebViewController = controller;
                },
                onProgressChanged: (InAppWebViewController controller , int progress){
                  setState(() {
                    _progress = progress / 100;
                  });
                },
              ),
              _progress < 1 ? Container(
                child: LinearProgressIndicator(
                  value: _progress,
                ),
              ):SizedBox()
            ],
          ),
        ),
      ),
    );
  }
}

Flutter InAppWebView Example

Video Tutorial

How to change Flutter android minSdkVersion & targetSdkVersion

0
How to Change minSdkVersion & TargetSdkVersion flutter sdk
How to Change minSdkVersion & TargetSdkVersion flutter sdk

Hi Guy’s Welcome to Proto Coders Point, In this article let’s checkout how to change minSdkVersion, targetSdkVersion, compileSdkVersion of your flutter project android module, follow below steps:

Flutter Change minSdkVersion, TargetSdkVersion

Step 1: Go to path where you have kept or installed flutter sdk, or where you have extracted flutter sdk zip file, May be at path:

C:\flutter

Step 2: Follow the below path to navigate to flutter.gradle file

C:\flutter\packages\flutter_tools\gradle

Step 3: search for flutter.gradle file in gradle folder

The complete path to file “flutter.gradle” is as below:

C:\flutter\packages\flutter_tools\gradle\flutter.gradle

Open the file in any editor

In this file, There is a class “FlutterExtension” where you can change sdkversion like minSdkVersion, targetSdkVersion, compileSdkVersion ,ndkVersion.

After Changing desired SdkVersion, save the file.

Video Tutorial

Completer – Handling Future async operation using Flutter Completer

0
Completer in Flutter
Completer in Flutter

In flutter a Completer is a Class that is built to manually complete a future task at some time in future. Basically it’s a way to generate & handle your own Future.

In other words, A ‘Completer’ is an inbuilt class that comes with DART SDK that is basically used to control & manage a ‘Future’ object. A ‘Future’ in flutter we can say it as a value that will be available in future at sometime in time, May be as soon as any asynchronous operation completes.

Video Tutorial on Flutter Completer


When to use completer in flutter

Just Imagine you have ordered a package from a ECommerce Application.

Now you are waiting fro the package to arrive a your door steps.

Then you know that package will be delivered sometime in future or you may know estimate time but not sure exectly when.

In this scenerio, Let’s say Future as Package & Completer as delivery person.

Now, when the delivery person arrives at doorstep the deliver the package, The delivery person make use of Completer to complete the Future i.e The delivery person will mark the package a delivered may be using OTP.


How to use Completer in Flutter App

Syntax of Completer

Completer<dataType> _completer = Completer<dataType>();

Code Example

void main() {
 Completer<String> myCompleter = Completer<String>();

 Future<String> futureValue = myCompleter.future;

 Future.delayed(Duration(seconds: 3),(){
   myCompleter.complete("Hello World");
 });

 futureValue.then((value) {
   print(value);
 });
}

In above code example, First we create a “Completer” object that will result a “String” & then we have created a Future Object by using property i.e. myCompleter.future The futureValue will be listen for myCompleter to complete.

Then, Just for delaying operation we simulate a asynchronous operation using Future.delayed method that sleep for 3 seconds , Then after 2 second the Future.delayed async function will execute & the operation complete, we call ‘completer.complete’ and set a string value “Welcome to Proto Coders Point”, thus this sets a “futureValue” as “Welcome to Proto Coders Point”.

after that we can make use of ‘then’ method to listen for the completion & it print the value on the screen.

Flutter Code Example – How to use Completer in Flutter

In below example, App user can manually complete the completer by clicking on a button.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(title: Text("Completer Example")),
            body: FutureWidget()));
  }
}

class FutureWidget extends StatefulWidget {
  @override
  _FutureWidgetState createState() => _FutureWidgetState();
}

class _FutureWidgetState extends State<FutureWidget> {
  Completer<String> _completer;

  void _handleButtonClick() {
    // Complete the future with the user input
    _completer.complete(_textEditingController.text);
  }

  TextEditingController _textEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();

    // Create the completer when the widget is initialized
    _completer = Completer<String>();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        TextField(
          controller: _textEditingController,
          decoration: InputDecoration(
            hintText: 'Enter some text',
            contentPadding: EdgeInsets.all(10.0),
          ),
        ),
        SizedBox(height: 20),
        ElevatedButton(
            onPressed: _handleButtonClick, child: Text("Complete Future")),
        SizedBox(height: 20),
        FutureBuilder(
          future: _completer.future,
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasData) {
                return Text("Future completed with: ${snapshot.data}");
              } else {
                return Text("Future completed with no data");
              }
            } else {
              return Text("Future not completed yet");
            }
          },
        ),
      ],
    );
  }
}

Programmatically Take Screenshots in Flutter

0
Programmatically take screenshot in flutter

In the digital age, screenshots are an essential component of daily routine  life. They is an efficient part to collect and share the data. that can be very useful in a variety of circumstances. Mobile application screenshots can be used for a variety of the purposes including testing, debugging, documentation etc.. This blog main topic will be how to take a screenshot in a Flutter app.

When testing, debugging, or showcasing the user interface of your Flutter application, the ability to take screenshots is a useful feature. Flutter’s straightforward API makes taking screenshots a breeze. In this blog, we’ll look at how to screenshot in Flutter.

Flutter is a well liked and lightweight framework for building mobile applications . That provides a quick and simple way to create visually appealing, powerful mobile apps for the iOS and Android operating systems. Developers can easily create original interfaces and layouts with Flutter’s high variety of widgets and tools.

How to Programmatically take a Screenshot in flutter

Get started…

Step 1) : Add the Screenshot Package

You must first include the Screenshot package in your project in order to take screenshots in Flutter. In your pubspec.yaml file, open the dependencies section, and then add the following code:

screenshot: ^any

Step 2) : After saving the file launch flutter pub. enter your terminal and start the package download.

flutter pub get

Step 3) : import the file

import 'package:screenshot/screenshot.dart';

Step 4) :Make a screenshot controller

The creation of a Screenshot Controller instance is the next step. You can use this controller to take a screenshot of your widget.

final _screenshotController = ScreenshotController();

Step 5) :Wrap the screenshot of your widget

You must wrap your widget in the Screenshot widget in order to take a screenshot of it. following code should be included in the build method :

Screenshot(
  controller: _screenshotController,
  child: //your widget here,
),

The child property holds the widget that we want to screenshot , and the controller property gives us access to the Screenshot Controller object we previously set up.

Step 6) : Taking a Screenshot

By calling the capture() method on the Screenshot Controller instance, you can finally take a screenshot. Here is an illustration of how to use a floating action button to invoke the capture() method:

FloatingActionButton(
  onPressed: () async {
    final image = await _screenshotController.capture();
    /// do something with the image
  },
  child: Icon(Icons.camera_alt),
),

Step 7) :How to Show or Save a Screenshot

After taking the screenshot you have the option of viewing it or saving it to as a  file. An example of how to show the screenshot that was taken is provided here below :

Image.memory(
  image,
  fit:BoxFit.cover,
),

here,…. you can save screenshot image data  to a file use writeAsBytes function in flutter framework .

final directory = await getApplicationDocumentsDirectory();
final imagePath = '${directory.path}/screenshot.png';

final file = File(imagePath);
await file.writeAsBytes(image);

Step 8) :Reduce the Controller Widget and Screenshot Widget.

It’s critical to remove the Screenshot widget and the Screenshot Controller instance from your code after the screenshot has been taken in order to avoid any performance impact. To accomplish this, set the controller property of the Screenshot widget to null:

Screenshot(
  controller: null,
  child: //your widget here,
),

Additionally, by removing the Screenshot Controller instance:
@override
void dispose() {
///Controller dispose here  
  super.dispose();
}

It’s over now! These easy steps will help you take screenshots of your Flutter app.


screenshot of a widget using RepaintBoundary in Flutter

Video Tutorial

i) : order to take the screenshots of widgets . we will use RepaintBoundary widget as the parent widget. Global key must be used to specify RepaintBoundary.

Visit Flutter RepaintBoundary for more information.

static GlobalKey screen = new GlobalKey();
 RepaintBoundary(
        key: screen,
     child: ChildWidgets(
   )

So that it can be quickly saved in device local storage and transformed into an image bites, the RepaintBoundary widget must then be converted to an image.

Step 1) :Use RepaintBoundary to create widget.

Make widget in your file called MyWidget or any name :

import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      child: Container(
        color: Colors.blue,
        width: 200,
        height: 200,
        child: Center(
          child: Text(
            'Hello World!',
            style: TextStyle(
              color: Colors.white,
              fontSize: 30,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }
}

This widget has a 300 pixel wide by 300 pixel high container with a white background a font size of 30 bold font weight blue background.

We must first create a GlobalKey object to identify the widget from which we want to take the screenshot. There will also be developed a function called captureScreenshot that will take a screenshot and store it on the device storage.

/// here Define the function to capture the screenshot
  Future<void> captureScreenshot() async {
    try {
      /// Find boundary of the RepaintBoundary widget
      RenderRepaintBoundary boundary =
          _globalKey.currentContext.findRenderObject();
      /// Convert the widget to image
      ui.Image image = await boundary.toImage(pixelRatio: 3.0);
      // Convert image to a byte data
      ByteData byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      /// Convert byte data to an Uint8List
      Uint8List pngBytes = byteData.buffer.asUint8List();
      /// Get the application documents directory to save the screenshot widget
      final directory = (await getApplicationDocumentsDirectory()).path;
      /// Create file object and save the screenshot
      File imgFile = File('$directory/screenshot.png');
      await imgFile.writeAsBytes(pngBytes);
      /// Print  message indicating that the screenshot has been taken
      print('Screenshot taken successfully' );
    } catch (e) {
      // Handle the error if there is any
      print(e);
    }
  }

This code creates a Flutter application that use  RepaintBoundary to take screenshot of a widget in flutter . The widget that needs to be captured is wrap in the RepaintBoundary widget .the widget is identified by a global key in flutter.

When the user selects the Take Screenshot button the screenshot is saved to the device local storage .The RepaintBoundary widget boundary is located the captureScreenshot function is invoked and the widget is converted to an image. the image is converted to byte data. byte data is converted to an Uint8List and screenshot is saved in local storage.

For , get this screenshots code , click here…..


Conclusion 👍

I hope you can put this to use.To take a screenshot. use the Flutter screenshot package. With the help of this package we can take screenshot in a specific widget or the entire application screen. In this blog post, we will look at using this package to take screenshot in Flutter application. This example code can be changed to suit your requirements.

Thanks for reading this article……

Have a beautiful day…..

How to use the Value Notifier in flutter.

0
flutter value Notifier

ValueNotifier is a unique subclass of Changenotifier that can hold a single value and alert widgets that are listening to it whenever that value changes. ValueNotifier extends Changenotifier.

ValueNotifier offers an easy and effective way to manage and update state in your application. making it a useful and lightweight tool for developing reactive data sources in Flutter.

When you need to update the UI due to changes in a value. ValueNotifier comes in handy. You can use a ValueNotifier for instance to keep track of changes to the value of a text field in a user interface . so that other UI elements can be updated to reflect the new value.

The main benefit of using a ValueNotifier over state management alternatives like setState or streams is that it is portable and simple to operate. It does not necessitate the creation of intricate streams and stream controllers, nor is it as resource-intensive as setState for straightforward use cases.

What is ValueNotifier?

Let’s first define ValueNotifier so that we can proceed to the specifics of how to use it in Flutter. A straightforward observable data model can be made using the class called ValueNotifier. It is a simplified version of the ChangeNotifier class, which forms the backbone of the reactive programming style used by Flutter. ValueNotifier has a single property named value that stores the model’s current value. The model alerts its listeners whenever its value changes. Due to this, it is simple to develop reactive Flutter applications, in which the UI is updated whenever the data changes.

How can ValueNotifier be used?

It’s very easy to use ValueNotifier in Flutter. You can create a ValueNotifier by providing it with an initial value. For instance , you  follow these steps to create a ValueNotifier that stores an integer value:

// syntax --> ValueNotifier<dataType> myValueNotifier = ValueNotifier<dataType>(value);

// Example :
ValueNotifier<int> myValueNotifier = ValueNotifier<int>(0);

In this example, we making a ValueNotifier that stores the value 0 as an integer.

When you have a use  ValueNotifier you can use the value property to read and modify its value. For instance you can follow these steps to read the value of the ValueNotifier:

Read the value of the ValueNotifier Object:

int currentValue = myValueNotifier.value;

ValueNotifier value property’s value can be modify by assigning  new value . For example the following steps can be used to update the ValueNotifier value to 100 :

myValueNotifier.value = 100;

The ValueNotifier notifier listeners updated whenever value is updated or changed . The addListener method can be used keep track of changes in ValueNotifier variable.

myValueNotifier.addListener(() {
  print('Value changed to ${myValueNotifier.value}');
});

In this example, we’re extending the myValueNotifier with a listener that prints a message whenever its value changes.

To build a basic data model that can be used to update the user interface, ValueNotifier is frequently used in Flutter widgets. ValueNotifier can be used in widgets by simply creating a new instance of it and passing it to the child widgets as necessary. Here’s a good example:

using ValueNotifier


class ValueNotifierExample extends StatelessWidget {
  ValueNotifierExample({Key? key}) : super(key: key);
  final ValueNotifier<int> myValueNotifier = ValueNotifier<int>(42);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: Colors.blue.shade900,title: const Text("Value notifier implement")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('Value: ${myValueNotifier.value}'),
          ElevatedButton(
            onPressed: () {
              myValueNotifier.value += 1;
            },
            child: const Text('Increment Value'),
          ),
        ],
      ),
    );
  }
}

Here is an example showing , how to create a ListView in Flutter using the ValueNotifier builder set:

import 'package:flutter/material.dart';

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

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

class _ListViewValueNotifierState extends State<ListViewValueNotifier> {
  ValueNotifier<int> selectedIndex = ValueNotifier<int>(0);

  List<String> items = [
    "Item 1",
    "Item 2",
    "Item 3",
    "Item 4",
    "Item 5",
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue.shade900,
        title: const Text("ListView with ValueNotifier"),
      ),
      body: ValueListenableBuilder(
        valueListenable: selectedIndex,
        builder: (BuildContext context, int index, Widget? child) {
          return ListView.builder(
            itemCount: items.length,
            itemBuilder: (BuildContext context, int i) {
              return ListTile(
                title: Text(items[i]),
                selected: i == index,
                onTap: () {
                  selectedIndex.value = i;
                },
              );
            },
          );
        },
      ),
    );
  }
}

Conclusion 👍

ValueNotifier is a component of Flutter’s core Reactive Programming Model, which enables the creation of responsive and effective user interfaces. A ValueNotifier is a simple class that enables the development of reactive data sources that alert listeners when their values change.

ValueNotifier offers an easy and effective way to manage and update state in your application, making it a useful and lightweight tool for developing reactive data sources in Flutter.

Thanks for reading this article 💙…..

Have a beautiful day…..

Create routes in flutter Navigation (Deep-Dive)

0
flutter routes
material page route flutter

An open-source framework called Flutter is used to create powerful, cross-platform mobile apps. The navigation system is one of the most crucial components of any mobile application. Routes a user-friendly and highly customizable navigation system is offered by Flutter. We’ll go into great detail about creating routes in Flutter in this blog .

An application with multiple pages is one in which we design screens with their own widgets one of which is always visible.

The screens are typically displayed in response to user interactions which is accomplished by using navigational functionalities.

What is Navigation?

In a Flutter application switching between screens or views is referred to as “navigation”. Any mobile application must have navigation because it allows users to move between the app’s various screens and interact with its features.

Each screen or view in Flutter is represented by a widget and navigation is accomplished by stacking routes. The previous screen is pushed onto the stack and the new screen is displayed when a user navigates to a new screen.

To implement navigation in an application Flutter offers various patterns and methods including:

Navigator widgets : The Navigator widget in Flutter controls a stack of Route objects that stand in for the app’s screens. It offers ways for developers to push and pop routes from the stack, allowing them to manage the application’s flow.

Named routes: Named routes let app developers give each screen in their application a special name so that users can find it using the Navigator.pushNamed() method.

Bottom navigation bar: A bottom navigation bar is a widget that enables users to quickly switch between the app’s various screens by displaying a list of icons or labels at the bottom of the screen.

Tabs: Users can switch between various categories or views on  screen by using tabs which offer a horizontal list of tab labels.

Drawer:  A drawer is a panel that slides out from the side of the screen and gives the user access to a list of navigation options.

These methods enable programmers to integrate flexible and user-friendly navigation system into their Flutter applications resulting in a seamless user experience.


What are Routes?

Routes in Flutter are a way for users to move between different screens or pages of your application. A widget and distinct route are used to represent each screen in your application. Push and pop operations, which are used to move around a stack, can be used to navigate routes.

The current screen is pushed onto a stack of screens when a user switches between them. The current screen is removed from the stack and the previous screen is shown when the user requests to return to the previous screen.

Making a Simple Route

In Flutter, building a simple route is very easy. Simply defining a widget to represent your screen and link it to a route name is all that is required.

Say we want to move from the home screen to the settings screen. We must create a new widget that represents the settings screen in order to create a route for the settings screen. 

Here’s an illustration:

import 'package:flutter/material.dart';

class SettingsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
      ),
      body: Center(
        child: Text('Settings Screen'),
      ),
    );
  }
}

Here… for an example is :In the previous illustration, we create a new widget called SettingsScreen that shows a straightforward screen with appBar and text widget in the center.

We must give our widget a route name now that we have it. The MaterialPageRoute class which generates a route that shows a full-screen modal dialog, can be used to achieve this. To create a route for our SettingsScreen, follow these steps:

MaterialPageRoute(
  builder: (context) => SettingsScreen(),
);

In the previous example a fresh MaterialPageRoute is made and connected to our SettingsScreen widget. callback function returns our widget builder parameter.


Choosing a Route to Follow

We can navigate to our route from our home screen now that we have defined it. The Navigator widget, which controls the navigation stack must be used in order to accomplish this.

Using the Navigator.push() method we can add a fresh route to the stack. Here an illustration:

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SettingsScreen()),
);

In the aforementioned example we call the Navigator.push() method passing the current BuildContext and our MaterialPageRoute object.

Pop the Route

To go back to the previous screen we can use the Navigator.pop() method. This method returns any data passed to the route along with the top route that was pulled from the navigation stack. Here’s an illustration:

Navigator.pop(context);

In the previous illustration, we used the Navigator.Using the pop() method, send the current BuildContext. This will take you back to the previous screen and pop the top route from the navigation stack

By assigning each route a distinct name, named routing organizes your app’s navigation and makes it simpler to move between screens. Named routing offers a way to navigate to a specific screen by using a named route as opposed to using the widget hierarchy.

The use of named routing in Flutter including how to define named routes pass data between screens, and handle route transitions will be covered in this blog.

Defining Named Routes

To use named routing in Flutter, you first need to define your routes. This is done in the main.dart file of your app, in the MaterialApp widget. The routes parameter, which is a map of String keys and WidgetBuilder values, is where you define your routes.

Let’s say, for illustration purposes, that our app has two screens: a home screen and a details screen. Our named routes can be described as follows:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      routes: {
        '/': (context) => FirstScreen(),
        '/second': (context) => SecondScreen(),
      },
    );
  }
}

here defined two routes in the example: “/” for the first screen and “/secondScreen” for the second screen. here, we set the initialRoute to “/,” which is the when app launch on the first screen.

Named routes

We defined here two routes in this  example : “/” for the home screen and 

“/details” for the details screen define . Additionally we set the initial Route to “/” which causes the app launch on the homeScreen.

Making your way to named routes

The Navigator.pushNamed() method which accepts the route name as a parameter can be used to navigate to a named route.

For instance  we could follow these steps to move from the home screen to the details screen:

Navigator.pushNamed(context, '/details'');

By doing this  the user would see the details screen . it would be pushed onto the navigation stack.


Data Transfer between Screens in named routes

You’ll frequently need to pass data between your applocations screens. By passing arguments to the Navigator.pushNamed() method .Let’s say, for illustration that we want to pass the selected item to the details screen from a list of items on the home screen. By giving the item to the Navigator as an argument. we can accomplish this. the pushNamed() function.

Navigator.pushNamed(context, '/details', arguments: item);
class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final item = ModalRoute.of(context)!.settings.arguments as Item;

    return Scaffold(
      appBar: AppBar(
        title: Text(data.title),
      ),
      body: Center(
        child: Text(data.description),
      ),
    );
  }

Managing Route Changes

You can design the way that screens transition within your app in addition to naming routes and getting there. This can be accomplished by specifying a unique transition animation for each route using the MaterialPageRoute function Object() { [native code] }.

Take a fade-in transition, for instance, which we might want to use for the details screen. Making a new MaterialPageRoute and setting its transitionDuration and pageBuilder properties would allow us to accomplish this:

When switching between screens, Flutter offers a variety of built-in transition animations that can be used. There are many of these, such as FadeTransition, SlideTransition, and ScaleTransition. By extending the MaterialPageRoute class and overriding the buildTransitions method, you can also produce your own original transition animation.

class SlideRightRoute extends PageRouteBuilder {
  final Widget page;
  SlideRightRoute({required this.page})
      : super(
          transitionDuration: Duration(milliseconds: 500),
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            var begin = Offset(1.0, 0.0);
            var end = Offset.zero;
            var tween = Tween(begin: begin, end: end);
            var offsetAnimation = animation.drive(tween);
            return SlideTransition(
              position: offsetAnimation,
              child: child,
            );
          },
          pageBuilder: (context, animation, secondaryAnimation) => page,
        );
}

Navigator.push(
  context,
  SlideRightRoute(page: DetailsScreen()),
);

We create a new SlideRightRoute class that extends PageRouteBuilder in the aforementioned example. In order to create a SlideTransition that slides the screen in from the right, we define the transitionsBuilder method and set the transitionDuration property to 500 milliseconds. The Navigator.push method then receives our custom route as a parameter.


Choosing a Different Transition Duration

The duration of the route transition animation can be set using the transitionDuration property. You can change the value from the default of 300 milliseconds to one of your choosing.

For instance, we could modify the transitionDuration property as follows to make our custom slide-in-right transition last for 750 milliseconds:

class SlideRightRoute extends PageRouteBuilder {
  SlideRightRoute({required Widget page})
      : super(
          transitionDuration: Duration(milliseconds: 750),
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            //...
          },
          pageBuilder: (context, animation, secondaryAnimation) => page,
        );
}

defaultRouteName

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/second': (context) => SecondScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Second Screen'),
          onPressed: () {
            Navigator.pushNamed(context, '/second');
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go back to Home Screen'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

The HomeScreen widget will be the first screen to be displayed when the programme is opened because the defaultRouteName attribute in this example is set to ‘/’. Each route in the app has a widget attached to it that should appear when the route is browsed to. These routes are defined by the routes parameter.

The Second’ route, which is represented by the SecondScreen widget is reached via the Navigator.pushNamed function. To return to the previous screen which in this instance is the HomeScreen widget use the Navigator.pop function.


PushReplacementNamed 

PushReplacementNamed is a method in Flutter , that lets you switch to a new screen while erasing the one that is currently on the navigation stack.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/second': (context) => SecondScreen(),
        '/third': (context) => ThirdScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Second Screen'),
          onPressed: () {
            Navigator.pushReplacementNamed(context, '/second');
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Third Screen'),
          onPressed: () {
            Navigator.pushReplacementNamed(context, '/third');
          },
        ),
      ),
    );
  }
}

class ThirdScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Third Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go back to Home Screen'),
          onPressed: () {
            Navigator.popUntil(context, ModalRoute.withName('/'));
          },
        ),
      ),
    );
  }
}



The HomeScreen and SecondScreen widgets in this example employ the pushReplacementNamed function to direct the user to the second and third routes, respectively. The current screen in the navigation stack gets replaced with the new screen when pushReplacementNamed is invoked.

The popUntil function is used by the ThirdScreen widget to return to the HomeScreen widget. The ModalRoute.withName(‘/’) predicate in this example matches the initial route, and the popUntil function continually pops the current route off the stack until the predicate supplied in its argument is true.


popAndPushNamed  

Pop the current screen off the navigation stack and push a new screen onto the stack all at once with Flutter’s popAndPushNamed function.

Here’s an illustration:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/second': (context) => SecondScreen(),
        '/third': (context) => ThirdScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Second Screen'),
          onPressed: () {
            Navigator.popAndPushNamed(context, '/second');
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Third Screen'),
          onPressed: () {
            Navigator.pushNamed(context, '/third');
          },
        ),
      ),
    );
  }
}

class ThirdScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Third Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go back to Home Screen'),
          onPressed: () {
            Navigator.popUntil(context, ModalRoute.withName('/'));
          },
        ),
      ),
    );
  }
}



In this illustration the HomeScreen widget popAndPushNamed function is used to simultaneously pop the active screen off the stack and put the “second” route into the stack. When you wish to replace the current screen with new one while also removing the current screen from the navigation stack this is useful.

When you wish to mimic a “refresh” of the current screen by replacing it with a new instance of the same screen, the popAndPushNamed function might be helpful.

pushNamedAndRemoveUntil

PushNamedAndRemoveUntil is a method in Flutter that lets you advance to a new screen while erasing all previous screens from the stack of screens you’re currently on, up until a certain condition is satisfied.

Here’s an illustration:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/second': (context) => SecondScreen(),
        '/third': (context) => ThirdScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Third Screen and remove previous screens'),
          onPressed: () {
            Navigator.pushNamedAndRemoveUntil(context, '/third', ModalRoute.withName('/'));
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Third Screen'),
          onPressed: () {
            Navigator.pushNamed(context, '/third');
          },
        ),
      ),
    );
  }
}

class ThirdScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Third Screen')),
      body: Center(
        child: RaisedButton(
          child: Text('Go back to Home Screen'),
          onPressed: () {
            Navigator.popUntil(context, ModalRoute.withName('/'));
          },
        ),
      ),
    );
  }
}

The HomeScreen widget in this example uses the pushNamedAndRemoveUntil function to browse to the “third” route and delete all previous screens from the navigation stack. A RoutePredicate is used as the second input to pushNamedAndRemoveUntil, and it defines the prerequisite for halting the removal of earlier routes. ModalRoute.withName(‘/’) in this situation is used to indicate that any routes that come before the ‘/’ route (the first route) should be dropped.

When you wish to start again with new screen after removing a number of screens from the navigation stack . the pushNamedAndRemoveUntil function might be helpful. When creating logout function for instance you could wish to utilize.  it to delete all screens associated with the user’s session and start again with the login screen.

restorablePopAndPushNamed

With the help of the Flutter method restorablePopAndPushNamed you can move to a named route while simultaneously deleting the current route from the navigation stack and saving it for later restoration. Here is an illustration of how to use Flutter’s restorablePopAndPushNamed with named routes:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/settings': (context) => SettingsScreen(),
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Go to Settings'),
          onPressed: () {
            Navigator.restorablePopAndPushNamed(context, '/settings');
          },
        ),
      ),
    );
  }
}

class SettingsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Settings Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Go back to Home'),
          onPressed: () {
            Navigator.restorablePop(context);
          },
        ),
      ),
    );
  }
}

Two arguments are required by restorablePopAndPushNamed: a BuildContext and a String specifying the name of the route to be navigated to. It removes the current route from the navigation stack and replaces it with the named route.

RestorablePop pops the current route off the navigation stack and goes back to the previous screen with just a BuildContext argument.

Conclusion 👍

We thoroughly examined how to create routes in Flutter in this blog post. Routes are a way to move between screens or pages in your application, and we discovered that each screen is represented by a widget and connected to a particular route.

Additionally, we learned how to create a fundamental route, how to use the Navigator.push() method to travel to a route, and how to return.

Thanks for reading this article…..

Have a good day……