Category: flutter dart

Flutter is an open-source UI software development kit created by Google. It is used to develop cross platform applications for Android, iOS, Linux, Mac, Windows, Google Fuchsia, Web platform, and the web from a single codebase. First described in 2015, Flutter was released in May 2017.

  • API testing in Flutter

    API testing in Flutter

    It is very common to use API in our Flutter projects. Testing makes the Flutter project very easy to maintain, in this way you will save a lot of debugging time. Also when you have testing in place you can always check whether API working as expected. 

    Let’s create a simple API endpoint in PHP in our local server. If you don’t anything about PHP web development, It’s quite fun to work in PHP. This PHP file just responds with a JSON which has a list of Books, nothing complex right? 

    Server:

    <?php
    
    $b1 = ['title' => 'Beginning App Development with Flutter', 'author' => 'Rap Payne'];
    $b2 = ['title' => 'Beginning Flutter: A Hands On Guide to App Development', 'author' => 'Marco L. Napoli'];
    $b2 = ['title' => 'Flutter Apprentice', 'author' => 'Vincenzo Guzzi, Kevin D Moore, Vincent Ngo and Michael Katz'];
    
    $books = [$b1, $b2];
    
    header("content-type: application/json; charset=UTF-8");
    echo json_encode($books, JSON_PRETTY_PRINT);
    
    [
        {
            "title": "Beginning App Development with Flutter",
            "author": "Rap Payne"
        },
        {
            "title": "Flutter Apprentice",
            "author": "Vincenzo Guzzi, Kevin D Moore, Vincent Ngo and Michael Katz"
        }
    ]

    Flutter:


    Let’s first create a flutter project called “api_test”, we will use VSCode for the rest of the project.

    flutter create api_test

    Let’s add http package by this command, run on your terminal.

    flutter pub add http

    Go to your lib folder and create two files model.dart and service.dart.

    Model: 

    On the model.dart creates a book class.

    class Book {
      final String title;
      final String author;
    
      Book({required this.title, required this.author});
    }

    API:

    In the service, class create an abstract class like this 

    abstract class BookApi {
    import 'package:api_test/model.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert' as convert;
    
    abstract class BookApi {
      Future<List<Book>> books();
    }
    
    class BookService implements BookApi {
      Future<List<Book>> books() async {
        var url = Uri.parse('http://localhost/flutter/book.php');
        var response = await http.get(url);
    
        //print(response.body);
        if (response.statusCode == 200) {
          final listResponse = convert.jsonDecode(response.body) as List;
          List<Book> books = listResponse
              .map(
                (e) => Book(
                  title: e['title'],
                  author: e['author'],
                ),
              )
              .toList();
          return books;
        } else {
          print('Request failed with status: ${response.statusCode}.');
          return [];
        }
      }
    }
    
    

    create another class in the same file for the above BookApi method implementation

    Test:

    Create a test file called book_service_test.dart in test folder

    import 'package:api_test/model.dart';
    import 'package:api_test/service.dart';
    import 'package:flutter_test/flutter_test.dart';
    
    void main() {
      var book_service = BookService();
    
      test('book api', () async {
        final result = await book_service.books();
        print(" test $result");
    
        expect(result.isNotEmpty, true);
        expect(result, isA<List<Book>>());
      });
    }
    

    Our tests are passed when the list is not empty and list has a book type.

    Download the full source code

    Spread the love
  • Flutter video player example

    Flutter video player example

    Very easy Flutter video player example, using chewie and and video_player library.

    The app plays video from a remote HTTP URL and it plays in portrait mode, when you exit the video player it maintains portrait mode on your device.

    pubspec.yaml

    name: video_player
    description: Flutter video player project.
    
    # The following line prevents the package from being accidentally published to
    # pub.dev using `pub publish`. This is preferred for private packages.
    publish_to: 'none' # Remove this line if you wish to publish to pub.dev
    
    # The following defines the version and build number for your application.
    # A version number is three numbers separated by dots, like 1.2.43
    # followed by an optional build number separated by a +.
    # Both the version and the builder number may be overridden in flutter
    # build by specifying --build-name and --build-number, respectively.
    # In Android, build-name is used as versionName while build-number used as versionCode.
    # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
    # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
    # Read more about iOS versioning at
    # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
    version: 1.0.0+1
    
    environment:
      sdk: ">=2.12.0 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
    
    
      # The following adds the Cupertino Icons font to your application.
      # Use with the CupertinoIcons class for iOS style icons.
      cupertino_icons: ^1.0.2
      video_player: ^2.1.14
      chewie: ^1.2.2
      
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
    
    # For information on the generic Dart part of this file, see the
    # following page: https://dart.dev/tools/pub/pubspec
    
    # The following section is specific to Flutter.
    flutter:
    
      # The following line ensures that the Material Icons font is
      # included with your application, so that you can use the icons in
      # the material Icons class.
      uses-material-design: true
    
      # To add assets to your application, add an assets section, like this:
      #assets:
      #   - images/a_dot_ham.jpeg
    
      # An image asset can refer to one or more resolution-specific "variants", see
      # https://flutter.dev/assets-and-images/#resolution-aware.
    
      # For details regarding adding assets from package dependencies, see
      # https://flutter.dev/assets-and-images/#from-packages
    
      # To add custom fonts to your application, add a fonts section here,
      # in this "flutter" section. Each entry in this list should have a
      # "family" key with the font family name, and a "fonts" key with a
      # list giving the asset and other descriptors for the font. For
      # example:
      # fonts:
      #   - family: Schyler
      #     fonts:
      #       - asset: fonts/Schyler-Regular.ttf
      #       - asset: fonts/Schyler-Italic.ttf
      #         style: italic
      #   - family: Trajan Pro
      #     fonts:
      #       - asset: fonts/TrajanPro.ttf
      #       - asset: fonts/TrajanPro_Bold.ttf
      #         weight: 700
      #
      # For details regarding fonts from package dependencies,
      # see https://flutter.dev/custom-fonts/#from-packages
    

    In your main function, make sure you run the app in portrait mode,

    void main() {
      WidgetsFlutterBinding.ensureInitialized();
    
      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
          .then((_) {
        runApp(MyApp());
      });
    }

    main.dart

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:inspiration_show/pages/home.dart';
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
    
      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
          .then((_) {
        runApp(MyApp());
      });
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Video Player',
          theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            primarySwatch: Colors.red,
          ),
          home: MyHomePage(title: 'Video Player Demo Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, required this.title}) : super(key: key);
    
      // This widget is the home page of your application. It is stateful, meaning
      // that it has a State object (defined below) that contains fields that affect
      // how it looks.
    
      // This class is the configuration for the state. It holds the values (in this
      // case the title) provided by the parent (in this case the App widget) and
      // used by the build method of the State. Fields in a Widget subclass are
      // always marked "final".
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      String appBarTitle = "Home";
    
      @override
      Widget build(BuildContext context) {
        // This method is rerun every time setState is called, for instance as done
        // by the _incrementCounter method above.
        //
        // The Flutter framework has been optimized to make rerunning build methods
        // fast, so that you can just rebuild anything that needs updating rather
        // than having to individually change instances of widgets.
        return Scaffold(
          appBar: AppBar(
            // Here we take the value from the MyHomePage object that was created by
            // the App.build method, and use it to set our appbar title.
            title: Text(appBarTitle),
          ),
          body: HomeWidget(),
        );
      }
    }
    

    home.dart

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:video_player/video_player.dart';
    import 'package:chewie/chewie.dart';
    
    class HomeWidget extends StatefulWidget {
      @override
      _VideoWidget createState() => _VideoWidget();
    }
    
    class _VideoWidget extends State<HomeWidget> {
      late VideoPlayerController videoPlayerController;
      late ChewieController chewieController;
    
      bool isReady = false;
    
      @override
      void initState() {
        super.initState();
        initializeVideoPlayer();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          margin: const EdgeInsets.all(16),
          child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
            Center(
              child: Container(
                height: 200,
                child: isReady == true
                    ? Chewie(controller: chewieController)
                    : Center(child: CircularProgressIndicator()),
              ),
            ),
          ]),
        );
      }
    
      @override
      void dispose() {
        super.dispose();
        videoPlayerController.dispose();
        chewieController.videoPlayerController.dispose();
    
        SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
      }
    
      Future<void> initializeVideoPlayer() async {
        videoPlayerController = VideoPlayerController.network(
            "https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1920_18MG.mp4");
        await Future.wait([videoPlayerController.initialize()]);
    
        chewieController = ChewieController(
            videoPlayerController: videoPlayerController,
            autoPlay: false,
            aspectRatio: 16 / 9,
            autoInitialize: true);
    
        setState(() {
          isReady = true;
        });
    
        chewieController.addListener(() {
          if (!chewieController.isFullScreen) {
            SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
          }
        });
      }
    }
    

    Download source code

    Spread the love
  • Read CSV file by Dart

    Read CSV file by Dart

    Reading CSV files in Dart language is easy. Make sure you have already installed Dart SDK, follow this tutorial if you haven’t Install Dart SDK on Mac, Windows and Linux

    For this tutorial, we are going to use the Dart plugin on PHPStorm by JetBrains.  To install the plugin on Mac go to PHPStorm -> Preferences -> Plugins and search for ‘Dart’. See my screenshot.

    Read CSV file by Dart

    Few more plugins for Dart

    Dart for Visual Studio Code   and Dart Plugin from JetBrains

    After successfully installing the plugin open PHPStorm go to File -> New Project and choose Dart -> Console Application. See the screenshot.

    Read CSV file by Dart

    PHPStorm will give you a project structure like this. We won’t use the dummy dart library file from lib folder. We will use only main.dart file from the bin folder.

    Read CSV file by Dart

    Delete all lines from main.dart the file and paste this code. Run the code (bottom of the page) from PHPStorm it will print the id, symbol, and open column from each row of the CSV file.

    Download the CSV file for testing

    import 'dart:io';
    import 'dart:async';
    import 'dart:convert';
    
    main(List arguments) {
      final File file = new File("~/Downloads/C_stock_data.csv");
    
      Stream<List> inputStream = file.openRead();
    
      inputStream
          .transform(utf8.decoder)       // Decode bytes to UTF-8.
          .transform(new LineSplitter()) // Convert stream to individual lines.
          .listen((String line) {        // Process results.
    
           List row = line.split(','); // split by comma
    
            String id = row[0];
            String symbol = row[1];
            String open = row[2];
            String low = row[3];
            String high = row[4];
            String close = row[5];
            String volume = row[6];
            String exchange = row[7];
            String timestamp = row[8];
            String date = row[9];
    
            print('$id, $symbol, $open');
    
          },
          onDone: () { print('File is now closed.'); },
          onError: (e) { print(e.toString()); });
    }

    Download project from github

    Spread the love