Category: 5. Advanced Concepts

https://cdn3d.iconscout.com/3d/premium/thumb/3d-software-settings-icon-download-in-png-blend-fbx-gltf-file-formats–setting-configuration-preferences-printing-pack-science-technology-icons-8549424.png?f=webp

  • Testing

    Testing is an activity, which is used for verifying and validating a software or application that is bug-free and meets the user requirements. It ensures that the actual result matches the expected result. It also helps to improve the software or application in terms of efficiency, usability, and accuracy.

    Testing is one of the most important phases in the application development life cycle to ensure the application is of high quality. It is the most consuming phase in the application or software development.

    Flutter framework provides excellent support for the automated testing of an application. Generally, automated testing categorizes into three types to completely test an application. They are as follows:

    1. Unit Testing
    2. Widget Testing
    3. Integration testing
    Flutter Testing

    Unit Testing

    It is the easiest method for testing an application or software. It tests a single function, method, or class. The goal of unit testing is to ensure the correctness of code under a variety of conditions. Generally, unit testing does not interact with user input, render on the screen, read or write data from the disk, and do not use external dependencies by default. When you use external dependencies, they are mocked out with packages like Mockito.

    Widget Testing

    Widget testing is used to tests a single widget. The goal of this testing is to ensure that the widget’s UI looks and interacts with other widgets as expected. The process of widget testing is similar to unit testing, but it is more comprehensive than a unit test. This testing involves multiple classes and requires a test environment to find more bugs. A widget, which is being tested, can receive and responds to user actions and events and able to instantiates the child widgets.

    Integration Testing

    An integration testing involves both the above testing along with the external components of the application. It validates a complete app or a large part of the app. The purpose of integration testing is to ensure that all the widgets and services work together as expected. It can also use to verify the app’s performance. Generally, integration testing runs on real devices such as Android emulator or iOS simulator.

    The trade-offs between different type of testing are given below:

    Unit TestingWidget TestingIntegration Testing
    ConfidenceLowHigherHighest
    MaintenanceCostLow HigherHighest
    DependenciesFewMoreMost
    Execution SpeedQuickQuickSlow

    We know that, in Flutter, everything is a widget. So, here, we are going to discuss the widget testing in detail.

    Introduction to Widget Testing

    In widget testing, you need some additional tools provided by the flutter_test package. This package provides the following tools to test the widget.

    • WidgetTester: It allows for building and interacting with widgets in a test environment.
    • testWidgets(): This method automatically creates a WidgetTester for each test case. It is used as a normal test() function. It accepts two arguments: test description and test code.
    • Finder class: It is used to search widgets in the test environment.
    • Matcher class: It helps to verify whether a Finder class locates a single widget or multiple widgets in the test environment.

    Let us learn how all of the above fit together with the following steps:

    Step 1: Add the flutter_test dependency.

    In the first step, we need to add a flutter_test dependency in the pubspec.yaml file. By default, it is already added to the dependency section.

    Step 2: Create a widget to test.

    Next, we have to create a widget for performing testing. The below code snippet creates a widget which contains title and message to display on the screen.

    class MyAppWidget extends StatelessWidget {  
    
      final String title;  
    
      final String message;  
    
      
    
      const MyWidget({  
    
        Key key,  
    
        @required this.title,  
    
        @required this.message,  
    
      }) : super(key: key);  
    
      
    
      @override  
    
      Widget build(BuildContext context) {  
    
        return MaterialApp(  
    
          title: 'Flutter Testing Demo',  
    
          home: Scaffold(  
    
            appBar: AppBar(  
    
              title: Text(title),  
    
            ),  
    
            body: Center(  
    
              child: Text(message),  
    
            ),  
    
          ),  
    
        );  
    
      }  
    
    }  

      Step 3: Create a testWidgets test.

      To test the widget, use testWidget() method. This method allows us to define a test and accept two arguments: test description and test code. It also creates a WidgetTester to work with the widget. The following code verifies that MyAppWidget displays the title and message.

      void main() {  
      
        testWidgets(' The widget contains a title and message', (WidgetTester tester) async {  
      
          // Write test code here.  
      
        });  
      
      }  

        Step 4: Build the widget using the WidgetTester.

        The WidgetTester provides a pumpWidget() method to build and render the provided widget. It creates the instance of MyAppWidget that displays The ‘Ti’ and ‘Msg’ as the title and message, respectively. The following code explains it more clearly.

        void main() {  
        
            testWidgets(The widget contains a title and message', (WidgetTester tester) async {  
        
                await tester.pumpWidget(MyWidget(title: 'Ti', message: 'Msg'));  
        
          
        
          });  
        
        } 

          Step 5: Search for the widget using a Finder.

          In this step, we will use the Finder class to search the widget tree for the title and message. It allows us to verify that the widget is displayed correctly. To do this, we need to use the find.text() method.

          void main() {  
          
              testWidgets(The widget contains a title and message', (WidgetTester tester) async {  
          
              await tester.pumpWidget(MyWidget(title: 'Ti', message: 'Msg'));  
          
            
          
              final titleFinder = find.text('Ti');  
          
              final messageFinder = find.text('Msg');  
          
            
          
            });  
          
          }

          Step 6: Verify the widget using a Matcher.

          Finally, we need to verify the text message appears on the screen by using the Matcher class. It ensures that the widget appears on the screen exactly once. We can see the following code to understand it.

          void main() {  
          
              testWidgets(The widget contains a title and message', (WidgetTester tester) async {  
          
              await tester.pumpWidget(MyWidget(title: 'Ti', message: 'Msg'));  
          
            
          
              final titleFinder = find.text('Ti');  
          
              final messageFinder = find.text('Msg');  
          
            
          
              expect(titleFinder, findsOneWidget);  
          
              expect(messageFinder, findsOneWidget);  
          
            });  
          
          }  

            Now, we will see the working example to understand the concept of widget testing. First, create a project in Android Studio and navigate to the test folder of the project directory. Now, open the widget_test.dart file and replace the following code:

            import 'package:flutter/material.dart';  
            
            import 'package:flutter_test/flutter_test.dart';  
            
              
            
            void main() {  
            
                testWidgets(The widget contains a title and message', (WidgetTester tester) async {  
            
                // Create the widget by telling the tester to build it.  
            
                await tester.pumpWidget(MyWidget(title: 'Ti', message: 'Msg'));  
            
              
            
                // Create the Finders.  
            
                final titleFinder = find.text('Ti');  
            
                final messageFinder = find.text('Msg');  
            
              
            
                expect(titleFinder, findsOneWidget);  
            
                expect(messageFinder, findsOneWidget);  
            
              });  
            
            }  
            
              
            
            class MyAppWidget extends StatelessWidget {  
            
              final String title;  
            
              final String message;  
            
              
            
              const MyAppWidget({  
            
                Key key,  
            
                @required this.title,  
            
                @required this.message,  
            
              }) : super(key: key);  
            
              
            
              @override  
            
              Widget build(BuildContext context) {  
            
                return MaterialApp(  
            
                  title: 'Flutter Testing Demo',  
            
                  home: Scaffold(  
            
                    appBar: AppBar(  
            
                      title: Text(title),  
            
                    ),  
            
                    body: Center(  
            
                      child: Text(message),  
            
                    ),  
            
                  ),  
            
                );  
            
              }  
            
            } 

              To perform testing, go to the Run menu and select the “test in widget_test.dart” option. It will run the test and give the result as the following screen:

              Flutter Testing
            1. Database Concepts

              A database is an organized collection of data, which supports the storage and manipulation of data and accessed electronically from a computer system. We can organize data into rows, columns, tables, and indexes. It makes data management easy. We can store many things in the database, like name, age, picture, image, file, pdf, etc.

              Flutter provides many packages to work with the database. The most used and popular packages are:

              • sqflite database: It allows to access and manipulate SQLite database.
              • Firebase database: It will enable you to access and manipulate the cloud database.

              SQLite Database

              SQLite is a popular database software library that provides a relational database management system for local/client storage. It is a light-weight and time-tested database engine and contains features like self-contained, server-less, zero-configuration, transactional SQL database engine.

              Flutter SDK does not support SQLite directly. Instead, it provides a plugin sqflite, which performs all operations on the database as similar to the SQLite library. The sqflite provides most of the core functionalities related to the database are as follows:

              • It creates or opens the SQLite database.
              • It can execute SQL statements easily.
              • It also provides an advanced query method to get information from the SQLite database.

              Let us see step by step how we can store and fetch data in the Flutter.

              Step 1: First, create a new project in Android Studio and add the dependencies in pubspec.yaml file.

              1. dependencies:  
              2.   flutter:  
              3.     sdk: flutter  
              4.   sqflite: any  
              5.   path_provider: any  
              • The sqflite package provides classes and functions to interact with the SQLite database.
              • The path_provider package provides functions to define the location of your database on the local system, such as TemporaryDirectory and ApplicationDocumentsDirectory.

              Step 2: Create a model class. In this step, we have to define the data that needs to be stored before creating a table to store information. The following code explains it easily.

              class Book {  
              
                final int id;  
              
                final String title;  
              
                final int price;  
              
                
              
                Book({this.id, this.title, this.price});  
              
              } 

                Step 3: Open the database. Here, we need to open the connection to the database. It requires two steps:

                1. Set the path to the database by using the getDtabasePath() method and combined it with the path package.
                2. Use openDatabase() function to open the database.
                // It allows to open the database and store the reference.  
                
                final Future<Database> database = openDatabase(  
                
                  join(await getDatabasesPath(), 'book_database.db'),  
                
                ); 

                  Step 4: Create the table. In this step, we have to create a table that stores information about the books. Here, we are going to create a table named books, which contains the id, title, and price of the books. They are represented as three columns in the book table.

                  final Future<Database> database = openDatabase(  
                  
                    join(await getDatabasesPath(), 'book_database.db'),  
                  
                    // When you create a database, it also needs to create a table to store books.  
                  
                    onCreate: (db, version) {  
                  
                      // Run the CREATE TABLE statement.  
                  
                      return db.execute(  
                  
                        "CREATE TABLE books(id INTEGER PRIMARY KEY, title TEXT, price INTEGER)",  
                  
                      );  
                  
                    },  
                  
                    // Set the version to perform database upgrades and downgrades.  
                  
                    version: 1,  
                  
                  );

                  Step 5: Insert a Book into the database. Here, you have to store information on the table about the various books. Inserting a book into the table involves two steps:

                  • Convert the Book into a Map
                  • Uses insert() method

                  The following code explains it more clearly.

                  // Update the Book class.  
                  
                  class Book{  
                  
                    final int id,  
                  
                    final String title;  
                  
                    final int price;  
                  
                    
                  
                    Book({this.id, this.title, this.price});  
                  
                    
                  
                    // It converts a Book into a Map. The keys correspond to the names of the columns in the database.  
                  
                    Map<String, dynamic> toMap() {  
                  
                      return {  
                  
                        'id': id,  
                  
                        'title': title,  
                  
                        'price': price,  
                  
                      };  
                  
                    }  
                  
                  }  
                  
                    
                  
                  Future<void> insertBook(Book book) async {  
                  
                    final Database db = await database;  
                  
                    await db.insert(  
                  
                      'books',  
                  
                      book.toMap(),  
                  
                      conflictAlgorithm: ConflictAlgorithm.replace,  
                  
                    );  
                  
                  }  
                  
                    
                  
                  // Create a Book and add it to the books table.  
                  
                  final b1 = Book(  
                  
                    id: 0,  
                  
                    title: 'Let Us C',  
                  
                    price: 350,  
                  
                  );  
                  
                    
                  
                  await insertBook(b1); 

                    Step 6: Retrieve the list of books. Now, we have stored the book into the database, and you can use a query to retrieve a particular book or list of all books. It involves two steps:

                    • Run a query that returns List<Map>.
                    • Convert the List<Map> into the List<Book>.

                    You can see the following code to understand it easily.

                    // This method retrieves all the books from the books table.  
                    
                    Future<List<Book>> books() async {  
                    
                      final Database db = await database;  
                    
                      
                    
                      // Use query for all Books.  
                    
                      final List<Map<String, dynamic>> maps = await db.query('maps');  
                    
                      
                    
                      return List.generate(maps.length, (i) {  
                    
                        return Book(  
                    
                          id: maps[i]['id'],  
                    
                          title: maps[i]['title'],  
                    
                          price: maps[i]['price'],  
                    
                        );  
                    
                      });  
                    
                    }  
                    
                      
                    
                    // It prints all the books.  
                    
                    print(await books());

                    Step 7: Update a Book in the database. You can use an update() method to update the book that you want. It involves two steps:

                    • Convert Book into the Map.
                    • Then, use where clause to update the book.

                    You can see the following code to understand it.

                    Future<void> updateBook(Book book) async {  
                    
                      final db = await database;  
                    
                      
                    
                      // Update the given Book.  
                    
                      await db.update(  
                    
                        'books',  
                    
                        book.toMap(),  
                    
                        // It ensure the matching id of a Book.  
                    
                        where: "id = ?",  
                    
                        whereArgs: [book.id],  
                    
                      );  
                    
                    }  
                    
                      
                    
                    // Update b1 price.  
                    
                    await updateBook(Book(  
                    
                      id: 0,  
                    
                      title: 'Let Us C',  
                    
                      price: 420,  
                    
                    ));  
                    
                      
                    
                    // Print the updated results.  
                    
                    print(await books());

                    Step 8: Delete a Book from the database. You can use the delete() method to delete the database. For this, you need to make a function that takes an id and delete the database of the matching id.

                    Future<void> deleteBook(int id) async {  
                    
                      final db = await database;  
                    
                      
                    
                      // This function removes books from the database.  
                    
                      await db.delete(  
                    
                        'books',  
                    
                        where: "id = ?",  
                    
                        whereArgs: [id],  
                    
                      );  
                    
                    }  

                      Let us see the complete code to understand how we can create a database file with sqflite plugin. For this, create a new Flutter project and the sqflite and path package into the pubspec.yaml file. Next, create a new file into the lib folder and insert the following code in this file. Now, connect the database with your UI and run the code.

                      import 'dart:async';  
                      
                        
                      
                      import 'packprice:path/path.dart';  
                      
                      import 'packprice:sqflite/sqflite.dart';  
                      
                        
                      
                      void main() async {  
                      
                        final database = openDatabase(  
                      
                          join(await getDatabasesPath(), 'book_database.db'),  
                      
                          onCreate: (db, version) {  
                      
                            return db.execute(  
                      
                              "CREATE TABLE books(id INTEGER PRIMARY KEY, title TEXT, price INTEGER)",  
                      
                            );  
                      
                          },  
                      
                          version: 1,  
                      
                        );  
                      
                        
                      
                        Future<void> insertBook(Book book) async {  
                      
                          // Get a reference to the database.  
                      
                          final Database db = await database;  
                      
                        
                      
                          await db.insert(  
                      
                            'books',  
                      
                            book.toMap(),  
                      
                            conflictAlgorithm: ConflictAlgorithm.replace,  
                      
                          );  
                      
                        }  
                      
                        
                      
                        Future<List<Book>> books() async {  
                      
                          final Database db = await database;  
                      
                        
                      
                          final List<Map<String, dynamic>> maps = await db.query('books');  
                      
                        
                      
                          return List.generate(maps.length, (i) {  
                      
                            return Book(  
                      
                              id: maps[i]['id'],  
                      
                              title: maps[i]['title'],  
                      
                              price: maps[i]['price'],  
                      
                            );  
                      
                          });  
                      
                        }  
                      
                        
                      
                        Future<void> updateBook(Book book) async {  
                      
                          final db = await database;  
                      
                          await db.update(  
                      
                            'books',  
                      
                            book.toMap(),  
                      
                            where: "id = ?",  
                      
                            whereArgs: [book.id],  
                      
                          );  
                      
                        }  
                      
                        
                      
                        Future<void> deleteBook(int id) async {  
                      
                          final db = await database;  
                      
                          await db.delete(  
                      
                            'books',  
                      
                            where: "id = ?",  
                      
                            whereArgs: [id],  
                      
                          );  
                      
                        }  
                      
                        
                      
                        var b1 = Book(  
                      
                          id: 0,  
                      
                          title: 'Let Us C',  
                      
                          price: 300,  
                      
                        );  
                      
                        
                      
                        await insertBook(b1);  
                      
                        
                      
                        print(await books());  
                      
                        
                      
                        b1 = Book(  
                      
                          id: b1.id,  
                      
                          title: b1.title,  
                      
                          price: b1.price,  
                      
                        );  
                      
                        await updateBook(b1);  
                      
                        
                      
                        print(await books());  
                      
                        
                      
                        await deleteBook(b1.id);  
                      
                        
                      
                        print(await books());  
                      
                      }  
                      
                        
                      
                      class Book {  
                      
                        final int id;  
                      
                        final String title;  
                      
                        final int price;  
                      
                        
                      
                        Book({this.id, this.title, this.price});  
                      
                        
                      
                        Map<String, dynamic> toMap() {  
                      
                          return {  
                      
                            'id': id,  
                      
                            'title': title,  
                      
                            'price': price,  
                      
                          };  
                      
                        }  
                      
                        @override  
                      
                        String toString() {  
                      
                          return 'Book{id: $id, title: $title, price: $price}';  
                      
                        }  
                      
                      } 
                      1. REST API

                        In this section, we are going to learn how we can access the REST API in the Flutter app. Today, most of the apps use remote data using APIs. So, this section will be the important part for those developers who want to make their carrier in Flutter.

                        Flutter provides http package to use http resources. The http package uses await and async features and provides many high-level methods such as read, get, post, put, head, and delete methods for sending and receiving data from remote locations. These methods simplify the development of REST-based mobile applications.

                        The detail explanation of the core methods of the http package are as follows:

                        Read: This method is used to read or retrieve the representation of resources. It requests the specified url by using the get method and returns the response as Future<String>.

                        Get: This method requests the specified url from the get method and returns a response as Future<response>. Here, the response is a class, which holds the response information.

                        Post: This method is used to submit the data to the specified resources. It requests the specified url by posting the given data and return a response as Future<response>.

                        Put: This method is utilized for update capabilities. It updates all the current representation of the target resource with the request payloads. This method request the specified url and returns a response as Future<response>.

                        Head: It is similar to the Get method, but without the response body.

                        Delete: This method is used to remove all the specified resources.

                        The http package also provides a standard http client class that supports the persistent connection. This class is useful when a lot of requests to be made on a particular server. It should be closed properly using the close() method. Otherwise, it works as an http class. The following code explains it more clearly.

                        var client = new http.Client();   
                        
                        try {   
                        
                           print(await client.get('https://www.javatpoint.com/'));   
                        
                        }   
                        
                        finally {   
                        
                           client.close();   
                        
                        }  

                          To fetch data from the internet, you need to follow these necessary steps:

                          Step 1: Install the latest http package and add it to the project.

                          To install the http package, open the pubspec.yaml file in your project folder and add http package in the dependency section. You can get the latest http package here and add it like:

                          dependencies:  
                          
                            http: <latest_version> 

                            You can import the http package as:

                            import 'package:http/http.dart' as http;  

                            Step 2: Next, make a network request by using the http package.

                            In this step, you need to make a network request by using the http.get() method

                            Future<http.Response> fetchPost() {  
                            
                              return http.get('https://jsonplaceholder.typicode.com/posts/1');  
                            
                            } 

                              In the above code, the Future is a class that contains an object. The object represents a potential value or error.

                              Step 3: Now, convert the response getting from network request into a custom Dart object.

                              First, you need to create a Post class. The Post class received data from the network request and includes a factory constructor, which creates Post from JSON. You can create a Post class as below:

                              class Post {  
                              
                                final int userId;  
                              
                                final int id;  
                              
                                final String title;  
                              
                                final String body;  
                              
                                
                              
                                Post({this.userId, this.id, this.title, this. description});  
                              
                                
                              
                                factory Post.fromJson(Map<String, dynamic> json) {  
                              
                                  return Post(  
                              
                                    userId: json['userId'],  
                              
                                    id: json['id'],  
                              
                                    title: json['title'],  
                              
                                    description: json['description'],  
                              
                                  );  
                              
                                }  
                              
                              }  

                                Now, you have to convert the http.response to a Post. The following code updates the fetchPost() function for returning a Future<Post>.

                                Future<Post> fetchPost() async {  
                                
                                  final response = await http.get( Give the link of JSON file');  
                                
                                  
                                
                                  if (response.statusCode == 200) {  
                                
                                    // If the server returns an OK response, then parse the JSON.  
                                
                                    return Post.fromJson(json.decode(response.body));  
                                
                                  } else {  
                                
                                    // If the response was umexpected, throw an error.  
                                
                                    throw Exception('Failed to load post');  
                                
                                  }  
                                
                                } 

                                  Step 4: Now, fetch the data with Flutter. You can call the fetch method in the initState(). The following code explains how you can fetch the data.

                                  class _MyAppState extends State<MyApp> {  
                                  
                                    Future<Post> post;  
                                  
                                    
                                  
                                    @override  
                                  
                                    void initState() {  
                                  
                                      super.initState();  
                                  
                                      post = fetchPost();  
                                  
                                    }  

                                    Step 5: Finally, display the data. You can display the data by using the FutureBuilder widget. This widget can work easily with async data sources.

                                    FutureBuilder<Post>(  
                                    
                                      future: post,  
                                    
                                      builder: (context, abc) {  
                                    
                                        if (abc.hasData) {  
                                    
                                          return Text(abc.data.title);  
                                    
                                        } else if (abc.hasError) {  
                                    
                                          return Text("${abc.error}");  
                                    
                                        }  
                                    
                                      
                                    
                                        // By default, it show a loading spinner.  
                                    
                                        return CircularProgressIndicator();  
                                    
                                      },  
                                    
                                    );

                                    Let us see the complete code to understand how Flutter works with REST API to fetch data from the network. You can learn more in detail from here.

                                    import 'dart:async';  
                                    
                                    import 'dart:convert';  
                                    
                                      
                                    
                                    import 'package:flutter/material.dart';  
                                    
                                    import 'package:http/http.dart' as http;  
                                    
                                      
                                    
                                    void main() => runApp(MyApp());  
                                    
                                      
                                    
                                    class MyApp extends StatefulWidget {  
                                    
                                      MyApp({Key key}) : super(key: key);  
                                    
                                      
                                    
                                      @override  
                                    
                                      _MyAppState createState() => _MyAppState();  
                                    
                                    }  
                                    
                                      
                                    
                                    class _MyAppState extends State<MyApp> {  
                                    
                                    Future<Post> post;  
                                    
                                      
                                    
                                      @override  
                                    
                                      void initState() {  
                                    
                                        super.initState();  
                                    
                                        post = fetchPost();  
                                    
                                      }  
                                    
                                      
                                    
                                      @override  
                                    
                                      Widget build(BuildContext context) {  
                                    
                                        return MaterialApp(  
                                    
                                          title: 'Flutter REST API Example',  
                                    
                                          theme: ThemeData(  
                                    
                                            primarySwatch: Colors.green,  
                                    
                                          ),  
                                    
                                          home: Scaffold(  
                                    
                                            appBar: AppBar(  
                                    
                                              title: Text('Flutter REST API Example'),  
                                    
                                            ),  
                                    
                                            body: Center(  
                                    
                                              child: FutureBuilder<Post>(  
                                    
                                                future: post,  
                                    
                                                builder: (context, abc) {  
                                    
                                                  if (abc.hasData) {  
                                    
                                                    return Text(abc.data.title);  
                                    
                                                  } else if (abc.hasError) {  
                                    
                                                    return Text("${abc.error}");  
                                    
                                                  }  
                                    
                                      
                                    
                                                  // By default, it show a loading spinner.  
                                    
                                                  return CircularProgressIndicator();  
                                    
                                                },  
                                    
                                              ),  
                                    
                                            ),  
                                    
                                          ),  
                                    
                                        );  
                                    
                                      }  
                                    
                                    }  
                                    
                                      
                                    
                                    Future<Post> fetchPost() async {  
                                    
                                      final response = await http.get('Give your JSON file web link.');  
                                    
                                      
                                    
                                      if (response.statusCode == 200) {  
                                    
                                        // If the call to the server was successful (returns OK), parse the JSON.  
                                    
                                        return Post.fromJson(json.decode(response.body));  
                                    
                                      } else {  
                                    
                                        // If that call was not successful (response was unexpected), it throw an error.  
                                    
                                        throw Exception('Failed to load post');  
                                    
                                      }  
                                    
                                    }  
                                    
                                      
                                    
                                    class Post {  
                                    
                                      final int userId;  
                                    
                                      final int id;  
                                    
                                      final String title;  
                                    
                                      final String description;  
                                    
                                      
                                    
                                      Post({this.userId, this.id, this.title, this. description});  
                                    
                                      
                                    
                                      factory Post.fromJson(Map<String, dynamic> json) {  
                                    
                                        return Post(  
                                    
                                          userId: json['userId'],  
                                    
                                          id: json['id'],  
                                    
                                          title: json['title'],  
                                    
                                          description: json[' description'],  
                                    
                                        );  
                                    
                                      }  
                                    
                                    }

                                    The JSON file is shown below.

                                    [   
                                    
                                       {   
                                    
                                          "userId": 01,   
                                    
                                          "id": 1,   
                                    
                                          "title": "iPhone",   
                                    
                                          "description": "iPhone is the very stylist phone ever"  
                                    
                                       },   
                                    
                                       {   
                                    
                                          "userId": 02,   
                                    
                                          "id": 2,   
                                    
                                          "title": "Pixel",   
                                    
                                          "description": "Pixel is the most feature phone ever"  
                                    
                                       },   
                                    
                                       {   
                                    
                                          "userId": 03,   
                                    
                                          "id": 3,   
                                    
                                          "title": "Laptop",   
                                    
                                          "description": "Laptop is most popular development tool"  
                                    
                                       },   
                                    
                                       {   
                                    
                                          "userId": 04,   
                                    
                                          "id": 4,   
                                    
                                          "title": "Tablet",   
                                    
                                          "description": "Tablet is the most useful device used for meeting"   
                                    
                                       }  
                                    
                                    ] 
                                    1. Slivers

                                      Sliver is a portion of the scrollable area which is used to achieve a custom scrolling effect. In other words, the sliver widget is a slice of the viewport. We can implement all of the scrollable views, such as ListView, GridView using slivers. It is a lower-level interface that provides excellent control over implementing a scrollable area. It is useful while scrolling large numbers of children widgets in a scrollable area. As they are based on the viewport, it can change their shape, size, and extent based on several events and offset.

                                      Flutter provides several kinds of slivers, some of them are given below:

                                      • SliverAppBar
                                      • SliverList
                                      • SliverGrid

                                      How to use slivers?

                                      It is to note that all of the sliver’s components should always be placed inside a CustomScrollView. After that, we can combine the list of slivers to make the custom scrollable area.

                                      What is CustomScrollView?

                                      CustomScrollView in Flutter is a scroll view that allows us to create various scrolling effects such as grids, lists, and expanding headers. It has a sliver property where we can pass a list of widgets that include SliverAppBar, SliverToBoxAdapter, SliverList, and SliverGrid, etc.

                                      Let us discuss each sliver in detail.

                                      SliverAppBar

                                      SliverAppBar is a material design app bar in Flutter that integrates with a CustomScrollView. Generally, we used it as the first child of CustomScrollView. It can vary in height and float above the other widget of the scroll view. It allows us to create an app bar with various scrolling effects.

                                      Properties of SliverAppBar

                                      The following are the essential properties of the SliverAppBar:

                                      actions: This property is used to create widgets right of the appBar title. Generally, it is an iconButton that represents common operations.

                                      title: This property is used to define the title to the SliverAppBar. It is similar to the AppBar title to give the name of the application.

                                      leading: This property is used to define a widget left to the title. Generally, it is used to place the Menu Drawer widget.

                                      backgroundColor: This property is used to define a background color to the sliver app bar.

                                      bottom: This property is used to create space to the bottom of the title, where we can define any widget according to our needs.

                                      expandedHeight: This property is used to specify the maximum height to the app bar that can be expanded while scrolling. It must be defined in a double value.

                                      floating: This property determines whether the app bar will be visible or not when the user scrolls towards the app bar.

                                      flexibleSpace: This property is used to define a widget which is stacked behind the toolbar and the tab bar. Its height is the same as the app bar’s overall height.

                                      Example

                                      In the below example, we will see how to use the SliverAppBar with CustomScrollView.

                                      import 'package:flutter/material.dart';  
                                      
                                        
                                      
                                      void main() => runApp(MyApp());  
                                      
                                        
                                      
                                      class MyApp extends StatelessWidget {  
                                      
                                        @override  
                                      
                                        Widget build(BuildContext context) {  
                                      
                                          return MaterialApp(  
                                      
                                            home: Scaffold(  
                                      
                                              body: CustomScrollView(  
                                      
                                                slivers: <Widget>[  
                                      
                                                  SliverAppBar(  
                                      
                                                    actions: <Widget>[  
                                      
                                                      Icon(Icons.person, size: 40,)  
                                      
                                                  ],  
                                      
                                                    title: Text("SliverAppBar Example"),  
                                      
                                                    leading: Icon(Icons.menu),  
                                      
                                                    backgroundColor: Colors.green,  
                                      
                                                    expandedHeight: 100.0,  
                                      
                                                    floating: true,  
                                      
                                                    pinned: true  
                                      
                                                  )  
                                      
                                                  // Place sliver widgets here  
                                      
                                                ],  
                                      
                                              ),  
                                      
                                            ),  
                                      
                                          );  
                                      
                                        }  
                                      
                                      } 

                                        Output

                                        When we run the app, we should get the UI of the screen similar to the below screenshot:

                                        Flutter Slivers

                                        SliverList

                                        SliverList is a sliver that places the children in a linear array or one-dimensional array. It takes a delegate parameter to provide the items in the list in a way they will scroll into view. We can specify the children’s list using a SliverChildListDelegate or build them with a SliverChildBuilderDelegate.

                                        Example

                                        In the below example, we will see how to use the SliverList with CustomScrollView.

                                        import 'package:flutter/material.dart';  
                                        
                                          
                                        
                                        void main() => runApp(MyApp());  
                                        
                                          
                                        
                                        class MyApp extends StatelessWidget {  
                                        
                                          @override  
                                        
                                          Widget build(BuildContext context) {  
                                        
                                            return MaterialApp(  
                                        
                                              home: Scaffold(  
                                        
                                                body: CustomScrollView(  
                                        
                                                  slivers: <Widget>[  
                                        
                                                    SliverAppBar(  
                                        
                                                      actions: <Widget>[  
                                        
                                                        Icon(Icons.person, size: 40,)  
                                        
                                                    ],  
                                        
                                                      title: Text("SliverList Example"),  
                                        
                                                      leading: Icon(Icons.menu),  
                                        
                                                      backgroundColor: Colors.green,  
                                        
                                                      expandedHeight: 100.0,  
                                        
                                                      floating: true,  
                                        
                                                      pinned: true  
                                        
                                                    ),  
                                        
                                                    SliverList(  
                                        
                                                      delegate: new SliverChildListDelegate(_buildList(20)),  
                                        
                                                    ),// Place sliver widgets here  
                                        
                                                  ],  
                                        
                                                ),  
                                        
                                              ),  
                                        
                                            );  
                                        
                                          }  
                                        
                                        }  
                                        
                                        List _buildList(int count) {  
                                        
                                          List<Widget> listItems = List();  
                                        
                                          for (int i = 0; i < count; i++) {  
                                        
                                            listItems.add(new Padding(padding: new EdgeInsets.all(16.0),  
                                        
                                                child: new Text(  
                                        
                                                    'Sliver Item ${i.toString()}',  
                                        
                                                    style: new TextStyle(fontSize: 22.0)  
                                        
                                                )  
                                        
                                            ));  
                                        
                                          }  
                                        
                                          return listItems;  
                                        
                                        }  

                                          Output

                                          When we run the app, we should get the UI of the screen similar to the below screenshot:

                                          Flutter Slivers

                                          SliverGrid

                                          SliverGrids places the children in a two-dimensional arrangement. It also uses a delegate to specify the children or an explicit list similar to the SliverList. But it has additional formatting to the cross-axis dimension on a grid. It allows the three ways to specify the grid layout:

                                          1. It uses Count Constructor for counting the number of items in the horizontal axis. See the below code:

                                          SliverGrid.count(  
                                          
                                            crossAxisCount: 3,  
                                          
                                            mainAxisSpacing: 20.0,  
                                          
                                            crossAxisSpacing: 20.0,  
                                          
                                            childAspectRatio: 3.0,  
                                          
                                            children: <Widget>[  
                                          
                                              Container(color: Colors.red),  
                                          
                                              Container(color: Colors.blue),  
                                          
                                              Container(color: Colors.green),  
                                          
                                              Container(color: Colors.red),  
                                          
                                              Container(color: Colors.blue),  
                                          
                                              Container(color: Colors.green),  
                                          
                                            ],  
                                          
                                          ),

                                          2. It uses Extent Constructor, which specifies the maximum width of the items. It is most useful when the grid items vary in size. It means we can limit how large space they should take up. See the below code:

                                          SliverGrid.extent(  
                                          
                                            maxCrossAxisExtent: 200,  
                                          
                                            mainAxisSpacing: 10.0,  
                                          
                                            crossAxisSpacing: 10.0,  
                                          
                                            childAspectRatio: 4.0,  
                                          
                                            children: <Widget>[  
                                          
                                              Container(color: Colors.orange),  
                                          
                                              Container(color: Colors.yellow),  
                                          
                                              Container(color: Colors.purple),  
                                          
                                              Container(color: Colors.pink),  
                                          
                                              Container(color: Colors.green),  
                                          
                                              Container(color: Colors.indigo),  
                                          
                                            ],  
                                          
                                          ), 

                                            3. It uses Default constructor which is pass in an explicit gridDelegate parameter:

                                            Example

                                            In the below example, we will see how to use the SliverGrid with CustomScrollView.

                                            import 'package:flutter/material.dart';  
                                            
                                              
                                            
                                            void main() => runApp(MyApp());  
                                            
                                              
                                            
                                            class MyApp extends StatelessWidget {  
                                            
                                              @override  
                                            
                                              Widget build(BuildContext context) {  
                                            
                                                return MaterialApp(  
                                            
                                                  home: Scaffold(  
                                            
                                                    body: CustomScrollView(  
                                            
                                                      slivers: <Widget>[  
                                            
                                                        SliverAppBar(  
                                            
                                                          actions: <Widget>[  
                                            
                                                            Icon(Icons.camera_front, size: 40,)  
                                            
                                                        ],  
                                            
                                                          title: Text("SliverGrid Example"),  
                                            
                                                          leading: Icon(Icons.menu),  
                                            
                                                          backgroundColor: Colors.green,  
                                            
                                                          expandedHeight: 100.0,  
                                            
                                                          floating: true,  
                                            
                                                          pinned: true  
                                            
                                                        ),  
                                            
                                                        SliverGrid(  
                                            
                                                          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(  
                                            
                                                            crossAxisCount: 4,  
                                            
                                                          ) ,  
                                            
                                                          delegate: SliverChildBuilderDelegate((BuildContext context, int index) {  
                                            
                                                            return new Container(  
                                            
                                                                color: _randomPaint(index),  
                                            
                                                                height: 150.0  
                                            
                                                            );  
                                            
                                                          }),  
                                            
                                                        ),  
                                            
                                                      ],  
                                            
                                                    ),  
                                            
                                                  ),  
                                            
                                                );  
                                            
                                              }  
                                            
                                            }  
                                            
                                            Color _randomPaint(int index) {  
                                            
                                              if (index % 3 == 0) {  
                                            
                                                return Colors.orange;  
                                            
                                              } else if (index % 3 == 1) {  
                                            
                                                return Colors.blue;  
                                            
                                              }  
                                            
                                              return Colors.red;  
                                            
                                            }  

                                              Output

                                              When we run the app, we should get the UI of the screen similar to the following screenshot:

                                              Flutter Slivers

                                              SliverFixedExtentList and SliverToBoxAdapter

                                              A SliverFixedExtentList is a sliver that holds multiple children with the same main-axis extent in a one-dimensional array or linear array. It is more efficient than SliverList because there is no need to perform layouts on its children to obtain the main-axis extent. It does not allow a gap between its children. It requires each child to have the SliverConstraints.crossAxisExtent in the cross axis and the itemExtent property on the main-axis.

                                              A SliverToBoxAdapter is a sliver that can hold only a single box widget. It is useful when we want to display only a single child widget in CustomScrollView to create a custom scroll effect. If we need to display multiple box widgets in a CustomScrollView, we must use the SliverList, SliverFixedExtentList, or SliverGrid.

                                              Example

                                              In the below example, we will see how to use the SliverFixedExtentList and SliverToBoxAdapter with CustomScrollView.

                                              import 'package:flutter/material.dart';  
                                              
                                                
                                              
                                              void main() => runApp(MyApp());  
                                              
                                                
                                              
                                              class MyApp extends StatelessWidget {  
                                              
                                                @override  
                                              
                                                Widget build(BuildContext context) {  
                                              
                                                  return MaterialApp(  
                                              
                                                    home: Scaffold(  
                                              
                                                      body: CustomScrollView(  
                                              
                                                        slivers: <Widget>[  
                                              
                                                          SliverAppBar(  
                                              
                                                            actions: <Widget>[  
                                              
                                                              Icon(Icons.camera_front, size: 40,)  
                                              
                                                          ],  
                                              
                                                            title: Text("Sliver Example"),  
                                              
                                                            leading: Icon(Icons.menu),  
                                              
                                                            backgroundColor: Colors.green,  
                                              
                                                            expandedHeight: 100.0,  
                                              
                                                            floating: true,  
                                              
                                                            pinned: true  
                                              
                                                          ),  
                                              
                                                          SliverFixedExtentList(  
                                              
                                                            itemExtent: 75,  
                                              
                                                            delegate: SliverChildListDelegate([  
                                              
                                                              Container(color: Colors.blue),  
                                              
                                                              Container(color: Colors.pink),  
                                              
                                                              Container(color: Colors.yellow),  
                                              
                                                            ]),  
                                              
                                                          ),  
                                              
                                                          SliverToBoxAdapter(  
                                              
                                                            child: Container(  
                                              
                                                              color: Colors.orange,  
                                              
                                                              padding: const EdgeInsets.all(16.0),  
                                              
                                                              child: Text('Sliver Grid Header', style: TextStyle(fontSize: 28)),  
                                              
                                                            ),  
                                              
                                                          ),  
                                              
                                                        ],  
                                              
                                                      ),  
                                              
                                                    ),  
                                              
                                                  );  
                                              
                                                }  
                                              
                                              }

                                              Output

                                              When we run the app, we should get the UI of the screen similar to the below screenshot:

                                              Flutter Slivers
                                            1. Google Maps

                                              A map is used to get information about the world simply and visually. It presents the world places by showing its shape and sizes, locations and distance between them. We can add a map in our application with the use of the Google Maps Flutter plugin. This plugin can automatically access the Google Maps servers, map display, and respond to user gestures. It also allows us to add markers to our map.

                                              Why use Google Maps with Flutter?

                                              Flutter developers prefer Google Maps for their application because they provide native performance for android and iOS both. It allows us to implement the code one time and permit them to run the code for both devices (android and iOS). Google Maps Flutter plugin is provided in the Google Map widget that supports initialCameraPosition, maptype and onMapCreated. We can set the position of the camera and marker in any place on the earth. We can design the marker according to our choice. It also comes with a zoom property in a cameraposition to provide the zooming in google map view on the initial page.

                                              Let us see step by step to how to add Google Maps in Flutter application.

                                              Step 1: Create a new project. Open this project in the IDE, navigate to the lib folder, and then open the pubspec.yaml file for setting the map.

                                              Step 2: In pubspec.yaml file, we need to add the Google Maps Flutter plugin in the dependency section, which is available as google_maps_flutter on pub.dartlang.org. After adding a dependency, click on the get package link to import the library in the main.dart file.

                                              dependencies:    
                                              
                                                flutter:    
                                              
                                                  sdk: flutter    
                                              
                                                cupertino_icons: ^0.1.2    
                                              
                                                google_maps_flutter: ^0.5.21 

                                                It ensures that we have left two spaces from the left side of a google_maps_flutter dependency while adding the dependencies.

                                                Step 3: The next step is to get an API key for your project. If we are using an Android platform, then follow the instructions given on Maps SDK for Android: Get API Key. After creating the API key, add it to the application manifest file. We can find this file by navigating to android/app/src/main/AndroidManifest.xml as follows:

                                                <manifest ...  
                                                
                                                  <application ...  
                                                
                                                    <meta-data android:name="com.google.android.geo.API_KEY"  
                                                
                                                               android:value="YOUR ANDROID API KEY HERE"/> 

                                                  Step 4: Next, import the package in the dart file as below:

                                                  import 'package:google_maps_flutter/google_maps_flutter.dart';  

                                                  Step 5: Now, we are ready to add a GoogleMap widget to start creating a UI to display the map.

                                                  Example

                                                  Let us understand it with the help of an example.

                                                  import 'package:flutter/material.dart';  
                                                  
                                                  import 'package:google_maps_flutter/google_maps_flutter.dart';  
                                                  
                                                    
                                                  
                                                  void main() => runApp(MyApp());  
                                                  
                                                    
                                                  
                                                  class MyApp extends StatefulWidget {  
                                                  
                                                    @override  
                                                  
                                                    _MyAppState createState() => _MyAppState();  
                                                  
                                                  }  
                                                  
                                                    
                                                  
                                                  class _MyAppState extends State<MyApp> {  
                                                  
                                                    GoogleMapController myController;  
                                                  
                                                    
                                                  
                                                    final LatLng _center = const LatLng(45.521563, -122.677433);  
                                                  
                                                    
                                                  
                                                    void _onMapCreated(GoogleMapController controller) {  
                                                  
                                                      myController = controller;  
                                                  
                                                    }  
                                                  
                                                    
                                                  
                                                    @override  
                                                  
                                                    Widget build(BuildContext context) {  
                                                  
                                                      return MaterialApp(  
                                                  
                                                        home: Scaffold(  
                                                  
                                                          appBar: AppBar(  
                                                  
                                                            title: Text('Flutter Maps Demo'),  
                                                  
                                                            backgroundColor: Colors.green,  
                                                  
                                                          ),  
                                                  
                                                          body: Stack(  
                                                  
                                                            children: <Widget>[  
                                                  
                                                              GoogleMap(  
                                                  
                                                                onMapCreated: _onMapCreated,  
                                                  
                                                                initialCameraPosition: CameraPosition(  
                                                  
                                                                  target: _center,  
                                                  
                                                                  zoom: 10.0,  
                                                  
                                                                ),  
                                                  
                                                              ),  
                                                  
                                                              Padding(  
                                                  
                                                                padding: const EdgeInsets.all(14.0),  
                                                  
                                                                child: Align(  
                                                  
                                                                  alignment: Alignment.topRight,  
                                                  
                                                                  child: FloatingActionButton(  
                                                  
                                                                    onPressed: () => print('You have pressed the button'),  
                                                  
                                                                    materialTapTargetSize: MaterialTapTargetSize.padded,  
                                                  
                                                                    backgroundColor: Colors.green,  
                                                  
                                                                    child: const Icon(Icons.map, size: 30.0),  
                                                  
                                                                  ),  
                                                  
                                                                ),  
                                                  
                                                              ),  
                                                  
                                                            ],  
                                                  
                                                          ),  
                                                  
                                                        ),  
                                                  
                                                      );  
                                                  
                                                    }  
                                                  
                                                  }

                                                  In the above code, we have noticed these terms:

                                                  mapController: It is similar to other controllers that we had seen in Flutter. It controls all activities on the GoogleMap class. Here, it manages the camera function, such as position, animation, zooming, etc.

                                                  onMapCreated: It is a method called for creating a map and takes a MapController as an argument.

                                                  initialCameraPosition: It is a required parameter that sets the camera position from where we want to start. It allows us to set which part of the world we want to point on the map.

                                                  stack: It is used to place other Flutter widgets on top of the map widget.

                                                  Output:

                                                  When we run the app, it should return the UI of the screen as below screenshot:

                                                  Flutter Google Maps

                                                  How to change the map appearance?

                                                  We can change the map appearance such as normal view, satellite view, etc. using mapType property. This property allows developers to display the type of map tiles. The GoogleMap widget offers mainly five types of tiles, which are given below:

                                                  • none: It does not display any map tiles.
                                                  • normal: It displays the tiles on the map with traffic, labels and subtle terrain information.
                                                  • satellite: It displays the satellite image (aerial photos) of the location.
                                                  • terrain: It displays the specific physical features of an area of land (indicates type and height of terrain).
                                                  • hybrid: It displays the satellite images with some labels or overlays.

                                                  We can do this by creating a variable _currentMapType in the above code to display the current map type and then add mapType: _currentMapType to the GoogleMap widget.

                                                  MapType _currentMapType = MapType.normal;  
                                                  
                                                    
                                                  
                                                  @override  
                                                  
                                                  Widget build(BuildContext context) {  
                                                  
                                                    return MaterialApp(  
                                                  
                                                      GoogleMap(  
                                                  
                                                        mapType: _currentMapType,  
                                                  
                                                      ),  
                                                  
                                                    );  
                                                  
                                                  }   

                                                    Next, we have to add a method to modify the value of _currentMapType inside a setState() function call. This method will update the map appearance for matching with the new value of _currentMapType variable.

                                                    void _onMapTypeButtonPressed() {  
                                                    
                                                      setState(() {  
                                                    
                                                        _currentMapType = _currentMapType = = MapType.normal  
                                                    
                                                            ? MapType.satellite  
                                                    
                                                            : MapType.normal;  
                                                    
                                                      });  
                                                    
                                                    } 

                                                      Finally, replace the onPressed property with _onMapTypeButtonPressed.

                                                      child: FloatingActionButton(  
                                                      
                                                        onPressed: _onMapTypeButtonPressed  
                                                      
                                                      ), 

                                                        Let us see the complete code to change the map appearance. Open the dart file and replace it with the below code:

                                                        import 'package:flutter/material.dart';  
                                                        
                                                        import 'package:google_maps_flutter/google_maps_flutter.dart';  
                                                        
                                                          
                                                        
                                                        void main() => runApp(MyApp());  
                                                        
                                                          
                                                        
                                                        class MyApp extends StatefulWidget {  
                                                        
                                                          @override  
                                                        
                                                          _MyAppState createState() => _MyAppState();  
                                                        
                                                        }  
                                                        
                                                          
                                                        
                                                        class _MyAppState extends State<MyApp> {  
                                                        
                                                          GoogleMapController myController;  
                                                        
                                                          
                                                        
                                                          final LatLng _center = const LatLng(45.521563, -122.677433);  
                                                        
                                                          
                                                        
                                                          MapType _currentMapType = MapType.normal;  
                                                        
                                                          
                                                        
                                                          void _onMapTypeButtonPressed() {  
                                                        
                                                            setState(() {  
                                                        
                                                              _currentMapType = _currentMapType == MapType.normal  
                                                        
                                                                  ? MapType.satellite  
                                                        
                                                                  : MapType.normal;  
                                                        
                                                            });  
                                                        
                                                          }  
                                                        
                                                          
                                                        
                                                          void _onMapCreated(GoogleMapController controller) {  
                                                        
                                                            myController = controller;  
                                                        
                                                          }  
                                                        
                                                          
                                                        
                                                          @override  
                                                        
                                                          Widget build(BuildContext context) {  
                                                        
                                                            return MaterialApp(  
                                                        
                                                              home: Scaffold(  
                                                        
                                                                appBar: AppBar(  
                                                        
                                                                  title: Text('Flutter Maps Demo'),  
                                                        
                                                                  backgroundColor: Colors.green,  
                                                        
                                                                ),  
                                                        
                                                                body: Stack(  
                                                        
                                                                  children: <Widget>[  
                                                        
                                                                    GoogleMap(  
                                                        
                                                                      onMapCreated: _onMapCreated,  
                                                        
                                                                      initialCameraPosition: CameraPosition(  
                                                        
                                                                        target: _center,  
                                                        
                                                                        zoom: 10.0,  
                                                        
                                                                      ),  
                                                        
                                                                      mapType: _currentMapType  
                                                        
                                                                    ),  
                                                        
                                                                    Padding(  
                                                        
                                                                      padding: const EdgeInsets.all(14.0),  
                                                        
                                                                      child: Align(  
                                                        
                                                                        alignment: Alignment.topRight,  
                                                        
                                                                        child: FloatingActionButton(  
                                                        
                                                                          onPressed: _onMapTypeButtonPressed,  
                                                        
                                                                          materialTapTargetSize: MaterialTapTargetSize.padded,  
                                                        
                                                                          backgroundColor: Colors.green,  
                                                        
                                                                          child: const Icon(Icons.map, size: 30.0),  
                                                        
                                                                        ),  
                                                        
                                                                      ),  
                                                        
                                                                    ),  
                                                        
                                                                  ],  
                                                        
                                                                ),  
                                                        
                                                              ),  
                                                        
                                                            );  
                                                        
                                                          }  
                                                        
                                                        }

                                                        Output:

                                                        When we run the app, it should return the UI of the screen as below screenshot:

                                                        Flutter Google Maps

                                                        If we click on the map icon, we will get the satellite image of our specified location. See the below image:

                                                        Flutter Google Maps

                                                        How to add a marker on the map?

                                                        A marker identifies the location on the map. We can add a marker on a map by using the markers property inside the GoogleMap widget. Generally, the marker is shown when we move our camera from one location to another. For example, if we want to move from Poland to California, we can see a marker on that particular location when the camera moves to California.

                                                        We can add a marker by creating a variable _markers that will store the map’s markers and then set this variable as the markers property in the GoogleMap widget.

                                                        final Set<Marker> _markers = {};  
                                                        
                                                        @override  
                                                        
                                                        Widget build(BuildContext context) {  
                                                        
                                                          return MaterialApp(  
                                                        
                                                            GoogleMap(  
                                                        
                                                              markers: _markers,  
                                                        
                                                            ),  
                                                        
                                                          );  
                                                        
                                                        }

                                                        Next, it is required to track the current camera position on the map by adding the below code:

                                                        LatLng _currentMapPosition = _center;  
                                                        
                                                          
                                                        
                                                        void _onCameraMove(CameraPosition position) {  
                                                        
                                                          _currentMapPosition = position.target;  
                                                        
                                                        }  
                                                        
                                                          
                                                        
                                                        @override  
                                                        
                                                        Widget build(BuildContext context) {  
                                                        
                                                          return MaterialApp(  
                                                        
                                                            GoogleMap(  
                                                        
                                                              onCameraMove: _onCameraMove,  
                                                        
                                                            ),  
                                                        
                                                          );  
                                                        
                                                        }   

                                                          Finally, we need to add a marker in the map by modifying the _markers inside a setState() function call.

                                                          void _onAddMarkerButtonPressed() {  
                                                          
                                                            setState(() {  
                                                          
                                                              _markers.add(Marker(  
                                                          
                                                                markerId: MarkerId(_lastMapPosition.toString()),  
                                                          
                                                                position: _currentMapPosition,  
                                                          
                                                                infoWindow: InfoWindow(  
                                                          
                                                                  title: 'Nice Place'  
                                                          
                                                                ),  
                                                          
                                                                icon: BitmapDescriptor. defaultMarkerWithHue(BitmapDescriptor.hueViolet)  
                                                          
                                                              ));  
                                                          
                                                            });  
                                                          
                                                          } 

                                                            Let us see the complete code to add marker to the map. Open the dart file and replace it with the below code:

                                                            import 'package:flutter/material.dart';  
                                                            
                                                            import 'package:google_maps_flutter/google_maps_flutter.dart';  
                                                            
                                                              
                                                            
                                                            void main() => runApp(MyApp());  
                                                            
                                                              
                                                            
                                                            class MyApp extends StatefulWidget {  
                                                            
                                                              @override  
                                                            
                                                              _MyAppState createState() => _MyAppState();  
                                                            
                                                            }  
                                                            
                                                              
                                                            
                                                            class _MyAppState extends State<MyApp> {  
                                                            
                                                              GoogleMapController mapController;  
                                                            
                                                              static final LatLng _center = const LatLng(45.521563, -122.677433);  
                                                            
                                                              final Set<Marker> _markers = {};  
                                                            
                                                              LatLng _currentMapPosition = _center;  
                                                            
                                                              
                                                            
                                                              void _onAddMarkerButtonPressed() {  
                                                            
                                                                setState(() {  
                                                            
                                                                  _markers.add(Marker(  
                                                            
                                                                    markerId: MarkerId(_currentMapPosition.toString()),  
                                                            
                                                                    position: _currentMapPosition,  
                                                            
                                                                    infoWindow: InfoWindow(  
                                                            
                                                                      title: 'Nice Place',  
                                                            
                                                                      snippet: 'Welcome to Poland'  
                                                            
                                                                    ),  
                                                            
                                                                    icon: BitmapDescriptor.defaultMarker,  
                                                            
                                                                  ));  
                                                            
                                                                });  
                                                            
                                                              }  
                                                            
                                                              
                                                            
                                                              void _onCameraMove(CameraPosition position) {  
                                                            
                                                                _currentMapPosition = position.target;  
                                                            
                                                              }  
                                                            
                                                              
                                                            
                                                              void _onMapCreated(GoogleMapController controller) {  
                                                            
                                                                mapController = controller;  
                                                            
                                                              }  
                                                            
                                                              
                                                            
                                                              @override  
                                                            
                                                              Widget build(BuildContext context) {  
                                                            
                                                                return MaterialApp(  
                                                            
                                                                  home: Scaffold(  
                                                            
                                                                    appBar: AppBar(  
                                                            
                                                                      title: Text('Flutter Maps Demo'),  
                                                            
                                                                      backgroundColor: Colors.green,  
                                                            
                                                                    ),  
                                                            
                                                                    body: Stack(  
                                                            
                                                                      children: <Widget>[  
                                                            
                                                                        GoogleMap(  
                                                            
                                                                          onMapCreated: _onMapCreated,  
                                                            
                                                                          initialCameraPosition: CameraPosition(  
                                                            
                                                                            target: _center,  
                                                            
                                                                            zoom: 10.0,  
                                                            
                                                                          ),  
                                                            
                                                                          markers: _markers,  
                                                            
                                                                          onCameraMove: _onCameraMove  
                                                            
                                                                        ),  
                                                            
                                                                        Padding(  
                                                            
                                                                          padding: const EdgeInsets.all(14.0),  
                                                            
                                                                          child: Align(  
                                                            
                                                                            alignment: Alignment.topRight,  
                                                            
                                                                            child: FloatingActionButton(  
                                                            
                                                                              onPressed: _onAddMarkerButtonPressed,  
                                                            
                                                                              materialTapTargetSize: MaterialTapTargetSize.padded,  
                                                            
                                                                              backgroundColor: Colors.green,  
                                                            
                                                                              child: const Icon(Icons.map, size: 30.0),  
                                                            
                                                                            ),  
                                                            
                                                                          ),  
                                                            
                                                                        ),  
                                                            
                                                                      ],  
                                                            
                                                                    ),  
                                                            
                                                                  ),  
                                                            
                                                                );  
                                                            
                                                              }  
                                                            
                                                            }  

                                                              Output:

                                                              Run the app, and we will get the UI of the screen as the first screenshot. When we click on the button, it displays the marker at the last location on the map. When we tapped the marker, the information is displayed that gives a title and snippet about the location.

                                                              Flutter Google Maps
                                                              Flutter Google Maps
                                                            1. Splash Screen

                                                              A splash screen is a launch screen, start screen, or boot screen, which is a graphical control element containing the image, logo, and current version of the software. It is the first screen of the app that displays whenever the application is loading. It can also be the app’s welcome screen that provides a simple initial experience when a mobile game or program is launching. The splash screen is just a display screen that allows users to look something while the hardware is loading to present software to the user.

                                                              The common elements of a splash screen contain a company name and logo or a title. The most common example of a splash screen is the Flutter logo on starting the Flutter application or Microsoft logo while starting the Microsoft operating system. In this tutorial, we are going to see how a splash screen is created in Flutter application.

                                                              Splash Screen Characteristics

                                                              The following are the essential characteristics of the splash screen:

                                                              • It is mainly used for branding or identity recognition of the application and puts the branding impression to users.
                                                              • It can also be used to show some loading progress indicator while the hardware is loading to present software to the user.
                                                              • When the loading of the splash screen completes, the user gets another functional screen that would be home screen or dashboard, then is forgotten. Once the loading completes, we cannot press the back button to return the splash screen.

                                                              Here we are going to explain two methods to add a splash screen in our application.

                                                              Method 1: In the first method, we will implement the Timer() function to create a splash screen in our app.

                                                              First, create a new project in the IDE you are using. Open the project, navigate to the lib folder, and replace the below code with the main.dart file.

                                                              import 'dart:async';  
                                                              
                                                              import 'package:flutter/material.dart';  
                                                              
                                                                
                                                              
                                                              void main() { runApp(MyApp());}  
                                                              
                                                                
                                                              
                                                              class MyApp extends StatelessWidget {  
                                                              
                                                                @override  
                                                              
                                                                Widget build(BuildContext context) {  
                                                              
                                                                  return MaterialApp(  
                                                              
                                                                    home: MyHomePage(),  
                                                              
                                                                    debugShowCheckedModeBanner: false,  
                                                              
                                                                  );  
                                                              
                                                                }  
                                                              
                                                              }  
                                                              
                                                                
                                                              
                                                              class MyHomePage extends StatefulWidget {  
                                                              
                                                                @override  
                                                              
                                                                SplashScreenState createState() => SplashScreenState();  
                                                              
                                                              }  
                                                              
                                                              class SplashScreenState extends State<MyHomePage> {  
                                                              
                                                                @override  
                                                              
                                                                void initState() {  
                                                              
                                                                  super.initState();  
                                                              
                                                                  Timer(Duration(seconds: 5),  
                                                              
                                                                          ()=>Navigator.pushReplacement(context,  
                                                              
                                                                          MaterialPageRoute(builder:  
                                                              
                                                                              (context) => HomeScreen()  
                                                              
                                                                          )  
                                                              
                                                                       )  
                                                              
                                                                  );  
                                                              
                                                                }  
                                                              
                                                                @override  
                                                              
                                                                Widget build(BuildContext context) {  
                                                              
                                                                  return Container(  
                                                              
                                                                      color: Colors.yellow,  
                                                              
                                                                      child:FlutterLogo(size:MediaQuery.of(context).size.height)  
                                                              
                                                                  );  
                                                              
                                                                }  
                                                              
                                                              }  
                                                              
                                                              class HomeScreen extends StatelessWidget {  
                                                              
                                                                @override  
                                                              
                                                                Widget build(BuildContext context) {  
                                                              
                                                                  return Scaffold(  
                                                              
                                                                    appBar: AppBar(title:Text("Splash Screen Example")),  
                                                              
                                                                    body: Center(  
                                                              
                                                                        child:Text("Welcome to Home Page",  
                                                              
                                                                            style: TextStyle( color: Colors.black, fontSize: 30)  
                                                              
                                                                        )  
                                                              
                                                                    ),  
                                                              
                                                                  );  
                                                              
                                                                }  
                                                              
                                                              } 

                                                                In the above code, we have a method initState() called once when the stateful widget is inserted in the widget tree. This method first called the super.initState() and then the Timer function. The timer function contains two arguments where the first is duration, and the second is action to be performed. We have specified duration time five seconds, and after completing the time, the current screen will be replaced with the main screen of the app, i.e., HomeScreen().

                                                                Output:

                                                                When we open the app, we will see the flutter logo first for 5 seconds, shown in the below screenshot.

                                                                Flutter Splash Screen

                                                                After completing the 5 seconds, it will display our application’s home screen shown in the below screenshot.

                                                                Flutter Splash Screen

                                                                Method 2: In the second method, we will use a splashscreen package to create a splash screen in our app. This package provides many attributes that are given below:

                                                                SplashScreen ({ Color loaderColor,  
                                                                
                                                                int seconds,   
                                                                
                                                                double photoSize,   
                                                                
                                                                Image image,   
                                                                
                                                                Text loadingText,   
                                                                
                                                                Color backgroundColor,  
                                                                
                                                                Text title,   
                                                                
                                                                TextStyle styleTextUnderTheLoader,   
                                                                
                                                                dynamic onClick,   
                                                                
                                                                dynamic navigateAfterSeconds,   
                                                                
                                                                ImageProvider<dynamic> imageBackground,   
                                                                
                                                                Gradient gradientBackground}) 

                                                                  First, create a new project in the IDE you are using. Open the project, navigate to the lib folder, and open the pubspec.yaml file where we need to add the splashscreen dependency as below:

                                                                  Flutter Splash Screen

                                                                  Now, open the main.dart file and replace it with the below code.

                                                                  import 'dart:async';  
                                                                  
                                                                  import 'package:flutter/material.dart';  
                                                                  
                                                                  import 'package:splashscreen/splashscreen.dart';  
                                                                  
                                                                    
                                                                  
                                                                  void main() { runApp(MyApp()); }  
                                                                  
                                                                    
                                                                  
                                                                  class MyApp extends StatelessWidget {  
                                                                  
                                                                    @override  
                                                                  
                                                                    Widget build(BuildContext context) {  
                                                                  
                                                                      return MaterialApp(  
                                                                  
                                                                        theme: ThemeData(  
                                                                  
                                                                          primarySwatch: Colors.green,  
                                                                  
                                                                        ),  
                                                                  
                                                                        home: SplashScreenPage(),  
                                                                  
                                                                        debugShowCheckedModeBanner: false,  
                                                                  
                                                                      );  
                                                                  
                                                                    }  
                                                                  
                                                                  }  
                                                                  
                                                                  class SplashScreenPage extends StatelessWidget {  
                                                                  
                                                                    @override  
                                                                  
                                                                    Widget build(BuildContext context) {  
                                                                  
                                                                      return SplashScreen(  
                                                                  
                                                                        seconds: 5,  
                                                                  
                                                                        navigateAfterSeconds: new HomeScreen(),  
                                                                  
                                                                        backgroundColor: Colors.yellow,  
                                                                  
                                                                        title: new Text('Flutter Javatpoint',textScaleFactor: 2,),  
                                                                  
                                                                        image: new Image.network(  
                                                                  
                                                                            'https://static.javatpoint.com/tutorial/flutter/images/flutter-creating-android-platform-specific-code3.png'  
                                                                  
                                                                        ),  
                                                                  
                                                                        loadingText: Text("Loading"),  
                                                                  
                                                                        photoSize: 150.0,  
                                                                  
                                                                        loaderColor: Colors.red,  
                                                                  
                                                                      );  
                                                                  
                                                                    }  
                                                                  
                                                                  }  
                                                                  
                                                                  class HomeScreen extends StatelessWidget {  
                                                                  
                                                                    @override  
                                                                  
                                                                    Widget build(BuildContext context) {  
                                                                  
                                                                      return Scaffold(  
                                                                  
                                                                        appBar: AppBar(title:Text("Splash Screen Example")),  
                                                                  
                                                                        body: Center(  
                                                                  
                                                                            child:Text("Welcome to Home Page",  
                                                                  
                                                                                style: TextStyle( color: Colors.black, fontSize: 30)  
                                                                  
                                                                            )  
                                                                  
                                                                        ),  
                                                                  
                                                                      );  
                                                                  
                                                                    }  
                                                                  
                                                                  } 

                                                                    In the above code, we have a home page as SplashScreenPage() that will return the SplashScreen class. This class has several properties for displaying the splash screen, such as title, image, backgroundcolor, gradientBackground, seconds, loadingText, etc. The second property is used for how much time the splash screen appears to the user, and after completion, it will navigate to a new screen, i.e., HomeScreen() in our app.

                                                                    Output:

                                                                    When we open the app, we will see the image and loading icon first for 5 seconds, shown in the below screenshot. When the specified time completes, we will navigate to the main page of the application.

                                                                    Flutter Splash Screen
                                                                  1. Packages

                                                                    A package is a namespace that contains a group of similar types of classes, interfaces, and sub-packages. We can think of packages as similar to different folders on our computers where we might keep movies in one folder, images in another folder, software in another folder, etc. In Flutter, Dart organizes and shares a set of functionality through a package. Flutter always supports shared packages, which is contributed by other developers to the Flutter and Dart ecosystem. The packages allow us to build the app without having to develop everything from scratch.

                                                                    The general structure of the package is given below (Assume a demo package as mycustom_package):

                                                                    lib/src/*: It contains private Dart code files.

                                                                    lib/mydemo_package.dart: It is a main Dart code file. We can import it into an application as below:

                                                                    We can also export any other code file into the main code file as below syntax:

                                                                    Export src/my_code.dart  

                                                                    lib/*: It is a directory, which contains the public code in the package. We can access this code as below:

                                                                    import 'package:mydemo_package/sub_folder/custom_file.dart'  

                                                                    pubspec.yaml: It is the project’s configuration file that will use a lot during working with the Flutter project. This file contains:

                                                                    • Project general settings such as name, description, and version of the project.
                                                                    • Project dependencies.
                                                                    • Project assets (e.g., images).

                                                                    Types of Packages

                                                                    According to the functionality, we can categorize the package into two types:

                                                                    1. Dart Package
                                                                    2. Plugin Package

                                                                    Dart Package: It is a general package, which is written in the dart language, such as a path package. This package can be used in both the environment, either it is a web or mobile platform. It also contains some Flutter specific functionality and thus has a dependency on the Flutter framework, such as fluro package.

                                                                    Plugin Package: It is a specialized Dart package that includes an API written in Dart code and depends on the Flutter framework. It can be combined with a platform-specific implementation for an underlying platform such as Android (using Java or Kotlin), and iOS (using Objective C or Swift). The example of this package is the battery and image picker plugin package.

                                                                    Develop a Flutter Package or Plugin

                                                                    Developing a Flutter plugin or package is similar to creating a Dart application or Dart package. But, it has some exceptions means plugin always uses system API specific to a platform such as Android or iOS to get the required functionality. Now, let us see step by step how to develop a package in Flutter.

                                                                    Step 1: First, open the Android Studio and click on File menu -> Select a New Flutter Project. A dialog box will appear on your screen.

                                                                    Flutter Packages

                                                                    Step 2: In this dialog box, you need to select a New Flutter Project option, as shown in the image below, and click on Next.

                                                                    Flutter Packages

                                                                    Step 3: In the next dialog box, enter all the details of your package, such as project name, location of your project, and project description. After filling all the details, click on Finish.

                                                                    Flutter Packages

                                                                    Step 4: Finally, your project is created. Now, open the flutter_custom_package.dart file and delete the default code created at the time of project creation. Then insert the following code. This code snippet creates an alert box package.

                                                                    library flutter_custom_package;  
                                                                    
                                                                      
                                                                    
                                                                    import 'package:flutter/material.dart';  
                                                                    
                                                                      
                                                                    
                                                                    class CustomPackageAlertBox {  
                                                                    
                                                                      static Future showCustomAlertBox({  
                                                                    
                                                                        @required BuildContext context,  
                                                                    
                                                                        @required Widget willDisplayWidget,  
                                                                    
                                                                      }) {  
                                                                    
                                                                        assert(context != null, "If context is null!!");  
                                                                    
                                                                        assert(willDisplayWidget != null, "If willDisplayWidget is null!!");  
                                                                    
                                                                        return showDialog(  
                                                                    
                                                                            context: context,  
                                                                    
                                                                            builder: (context) {  
                                                                    
                                                                              return AlertDialog(  
                                                                    
                                                                                shape: RoundedRectangleBorder(  
                                                                    
                                                                                  borderRadius: BorderRadius.all(Radius.circular(20)),  
                                                                    
                                                                                ),  
                                                                    
                                                                                content: Column(  
                                                                    
                                                                                  mainAxisSize: MainAxisSize.min,  
                                                                    
                                                                                  children: <Widget>[  
                                                                    
                                                                                    willDisplayWidget,  
                                                                    
                                                                                    MaterialButton(  
                                                                    
                                                                                      color: Colors.white70,  
                                                                    
                                                                                      child: Text('Close Alert'),  
                                                                    
                                                                                      onPressed: () {  
                                                                    
                                                                                        Navigator.of(context).pop();  
                                                                    
                                                                                      },  
                                                                    
                                                                                    )  
                                                                    
                                                                                  ],  
                                                                    
                                                                                ),  
                                                                    
                                                                                elevation: 12,  
                                                                    
                                                                              );  
                                                                    
                                                                            });  
                                                                    
                                                                      }  
                                                                    
                                                                    }

                                                                    Now, you need to test your newly created package. To test the package, create a new project. In this project, first, open the pubspec.yaml file and the following code in the dependency section.

                                                                    dependencies:   
                                                                    
                                                                       flutter:   
                                                                    
                                                                          sdk: flutter   
                                                                    
                                                                       flutter_custom_package:   
                                                                    
                                                                          path: ../ 

                                                                      When you add the custom package in pubspec.yaml file, Android Studio will alert you to update this file. To update the file, click on the Get dependencies and make sure that you have an internet connection during updating of file. The Android Studio automatically get the package from the internet and configure it for your application. Now, you are able to use this package. You can import the package in the dart file as below line:

                                                                      import 'package: flutter_custom_package/flutter_custom_package.dart';  

                                                                      How to Publish a Package

                                                                      When you have successfully implemented a package, you can publish it on the pub.dev, so that anyone can use it easily in the project.

                                                                      Before publishing the package, make sure that the content of pubspec.yaml, README.md, and CHANGELOG.md file is complete and correct.

                                                                      Next, run the following command in the terminal window to analyze every phase of the package.

                                                                      $ flutter pub publish --dry-run  

                                                                      Finally, you need to run the following command to publish the package.

                                                                      $ flutter pub publish  
                                                                    1. Creating Android Platform-Specific Code

                                                                      In this section, we are going to see how we can write custom platform-specific code in Flutter. Flutter is an excellent framework, which provides a mechanism to handle/access platform-specific features. This feature allows the developer to extend the functionality of the Flutter framework. Some of the essential platform-specific functionality that can be accessed easily through the framework are camera, battery level, browser, etc.

                                                                      Flutter uses a flexible system to call platform-specific API either available on Android in Java or Kotlin code, or in Objective-C or Swift code on iOS. The general idea of accessing the platform-specific code in Flutter is through the messaging protocol. The messages are passed between the client (UI) and Host (Platform) using the common message channel. It means the clients sends a message to the Host by using this message channel. Next, the Host listens on that message channel, receives the message, does the appropriate functionality, and finally returns the result to the client.

                                                                      The following block diagram shows the appropriate platform-specific code architecture.

                                                                      Flutter Creating Android Platform-Specific Code

                                                                      The messaging channel uses a standard message codec (StandardMessageCodec class), which supports efficient binary serialization of JSON like values, such as string, Boolean, numbers, byte buffers, and List and Maps, etc. The serialization and deserialization of these values work automatically between clients and hosts when you send and receive values.

                                                                      The following table shows how dart values are received on Android and iOS platform and vice-versa:

                                                                      DartAndroidiOS
                                                                      nullnullnil (NSNull when nested)
                                                                      booljava.lang.BooleanNSNumber numberWithBool:
                                                                      intjava.lang.IntegerNSNumber numberWithInt:
                                                                      doublejava.lang.DoubleNSNumber numberWithDouble:
                                                                      Stringjava.lang.StringNSString:
                                                                      Uint8Listbyte[]FlutterStandardTypedData typedDataWithBytes:
                                                                      Int32Listint[]FlutterStandardTypedData typedDataWithInt32:
                                                                      Int64Listlong[]FlutterStandardTypedData typedDataWithInt64:
                                                                      Float64Listdouble[]FlutterStandardTypedData typedDataWithFloat64:
                                                                      Listjava.util.ArrayListNSArray
                                                                      Mapjava.util.HashMApNSDictionary

                                                                      Let us create a simple application to demonstrate how to call a platform-specific API to open a browser. To do this, we need to create a Flutter project in Android Studio and insert the following code in the main.dart file.

                                                                      import 'package:flutter/material.dart';  
                                                                      
                                                                      import 'dart:async';  
                                                                      
                                                                      import 'package:flutter/services.dart';  
                                                                      
                                                                        
                                                                      
                                                                      void main() => runApp(MyApp());  
                                                                      
                                                                      class MyApp extends StatelessWidget {  
                                                                      
                                                                        @override  
                                                                      
                                                                        Widget build(BuildContext context) {  
                                                                      
                                                                          return MaterialApp(  
                                                                      
                                                                            title: 'Flutter DemoApplication',  
                                                                      
                                                                            theme: ThemeData(  
                                                                      
                                                                              primarySwatch: Colors.green,  
                                                                      
                                                                            ),  
                                                                      
                                                                            home: MyHomePage(  
                                                                      
                                                                                title: 'Flutter Platform Specific Page'  
                                                                      
                                                                            ),  
                                                                      
                                                                          );  
                                                                      
                                                                        }  
                                                                      
                                                                      }  
                                                                      
                                                                      class MyHomePage extends StatelessWidget {  
                                                                      
                                                                        MyHomePage({Key key, this.title}) : super(key: key);  
                                                                      
                                                                        final String title;  
                                                                      
                                                                        static const platform = const MethodChannel('flutterplugins.javatpoint.com/browser');  
                                                                      
                                                                        Future<void> _openBrowser() async {  
                                                                      
                                                                          try {  
                                                                      
                                                                            final int result = await platform.invokeMethod('openBrowser', <String, String>{  
                                                                      
                                                                              'url': "https://www.javatpoint.com"  
                                                                      
                                                                            });  
                                                                      
                                                                          }  
                                                                      
                                                                          on PlatformException catch (e) {  
                                                                      
                                                                            // Unable to open the browser  
                                                                      
                                                                            print(e);  
                                                                      
                                                                          }  
                                                                      
                                                                        }  
                                                                      
                                                                        @override  
                                                                      
                                                                        Widget build(BuildContext context) {  
                                                                      
                                                                          return Scaffold(  
                                                                      
                                                                            appBar: AppBar(  
                                                                      
                                                                              title: Text(this.title),  
                                                                      
                                                                            ),  
                                                                      
                                                                            body: Center(  
                                                                      
                                                                              child: RaisedButton(  
                                                                      
                                                                                child: Text('Click Here'),  
                                                                      
                                                                                onPressed: _openBrowser,  
                                                                      
                                                                              ),  
                                                                      
                                                                            ),  
                                                                      
                                                                          );  
                                                                      
                                                                        }  
                                                                      
                                                                      } 

                                                                        In the above file, we have imported a service.dart file, which includes the functionality to invoke the platform-specific code. In the MyHomePage widget, we have created a message channel and write a method _openBrowser to invoke the platform-specific code.

                                                                        Future<void> _openBrowser() async {  
                                                                        
                                                                          try {  
                                                                        
                                                                            final int result = await platform.invokeMethod('openBrowser', <String, String>{  
                                                                        
                                                                              'url': "https://www.javatpoint.com"  
                                                                        
                                                                            });  
                                                                        
                                                                          }  
                                                                        
                                                                          on PlatformException catch (e) {  
                                                                        
                                                                            // Unable to open the browser   
                                                                        
                                                                         print(e);  
                                                                        
                                                                          }  
                                                                        
                                                                        } 

                                                                          Finally, we have created a button to open the browser.

                                                                          Now, we need to provide the custom platform-specific implementation. To do this, navigate to the Android folder of your Flutter project and select the Java or Kotlin file and insert the following code into the MainActivity file. This code might change according to the Java or Kotlin language.

                                                                          package com.javatpoint.flutterplugins.flutter_demoapplication  
                                                                          
                                                                            
                                                                          
                                                                          import android.app.Activity  
                                                                          
                                                                          import android.content.Intent  
                                                                          
                                                                          import android.net.Uri  
                                                                          
                                                                          import android.os.Bundle  
                                                                          
                                                                          import io.flutter.app.FlutterActivity  
                                                                          
                                                                          import io.flutter.plugin.common.MethodCall  
                                                                          
                                                                          import io.flutter.plugin.common.MethodChannel  
                                                                          
                                                                          import io.flutter.plugin.common.MethodChannel.MethodCallHandler  
                                                                          
                                                                          import io.flutter.plugin.common.MethodChannel.Result  
                                                                          
                                                                          import io.flutter.plugins.GeneratedPluginRegistrant  
                                                                          
                                                                            
                                                                          
                                                                           class MainActivity:FlutterActivity() {  
                                                                          
                                                                              override fun onCreate(savedInstanceState:Bundle?) {  
                                                                          
                                                                                  super.onCreate(savedInstanceState)  
                                                                          
                                                                                  GeneratedPluginRegistrant.registerWith(this)  
                                                                          
                                                                                  MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->  
                                                                          
                                                                                  val url = call.argument<String>("url")  
                                                                          
                                                                                  if (call.method == "openBrowser") {  
                                                                          
                                                                                      openBrowser(call, result, url)  
                                                                          
                                                                                  } else {  
                                                                          
                                                                                      result.notImplemented()  
                                                                          
                                                                                  }  
                                                                          
                                                                              }  
                                                                          
                                                                           }  
                                                                          
                                                                           private fun openBrowser(call:MethodCall, result:Result, url:String?) {  
                                                                          
                                                                              val activity = this  
                                                                          
                                                                              if (activity == null)  
                                                                          
                                                                              {  
                                                                          
                                                                                  result.error("UNAVAILABLE", "It cannot open the browser without foreground activity", null)  
                                                                          
                                                                                  return  
                                                                          
                                                                              }  
                                                                          
                                                                              val intent = Intent(Intent.ACTION_VIEW)  
                                                                          
                                                                              intent.data = Uri.parse(url)  
                                                                          
                                                                              activity!!.startActivity(intent)  
                                                                          
                                                                              result.success(true as Any)  
                                                                          
                                                                           }  
                                                                          
                                                                            
                                                                          
                                                                           companion object {  
                                                                          
                                                                              private val CHANNEL = "flutterplugins.javatpoint.com/browser"  
                                                                          
                                                                           }  
                                                                          
                                                                          }  

                                                                            In the MainActivity.kt file, we have created a method openBrowser() to open the browser.

                                                                            private fun openBrowser(call:MethodCall, result:Result, url:String?) {  
                                                                            
                                                                                val activity = this  
                                                                            
                                                                                if (activity == null)  
                                                                            
                                                                                {  
                                                                            
                                                                                    result.error("UNAVAILABLE", "It cannot open the browser without foreground activity", null)  
                                                                            
                                                                                    return  
                                                                            
                                                                                }  
                                                                            
                                                                                val intent = Intent(Intent.ACTION_VIEW)  
                                                                            
                                                                                intent.data = Uri.parse(url)  
                                                                            
                                                                                activity!!.startActivity(intent)  
                                                                            
                                                                                result.success(true as Any)  
                                                                            
                                                                             }  

                                                                              Output

                                                                              Now, run the app in your android studio, you will get the following output. When you click on the button Click Here, you can see that the browser home page screen is launched.

                                                                              Flutter Creating Android Platform-Specific Code
                                                                              Flutter Creating Android Platform-Specific Code