Package Usage Example

Now that you know how to install packages, you’ll get to see packages in action.

Getting Started

We are going to build a simple app that displays the phone’s battery and connectivity state using the battery[28] and connectivity[29] packages from Pub:

images/Packages/app.png

To use those packages, we’ll start by adding the packages to our app’s dependencies, and you can do that by adding the following to the dependencies in pubspec.yaml:

 connectivity: ​^0.3.1
 battery: ​^0.2.2

And import the packages in our code by adding to the top of the main Dart file the following:

 import​ ​'dart:async'​;
 
 import​ ​'package:flutter/material.dart'​;
 import​ ​'package:battery/battery.dart'​;
 import​ ​'package:connectivity/connectivity.dart'​;

In addition to the packages we download from Pub, we also need Flutter’s standard Material Design API and Dart’s async library, which is needed to properly handle the asynchronous nature of the packages we are using.

The Main Function and Home Page Definition

The main function looks like any other main function that has been shown throughout this book:

 void​ ​main​() => runApp(
  MaterialApp(
  title: ​"Battery and connectivity status"​,
  theme: ThemeData(primarySwatch: Colors.green),
  home: HomePage(​"Dashboard"​),
  )
 );

The home page will be a Stateful widget, since we want it to change when the battery or connectivity state changes:

 class​ HomePage ​extends​ StatefulWidget {
  HomePage(​this​.title);
 
 final​ ​String​ title;
 
  HomePageState createState() => HomePageState();
 }

Defining the Home Page’s State

Each battery and connectivity state is going to be shown in the form of a string (like Mobile Data or Full) and an icon, with each status being represented by a different color:

 class​ HomePageState ​extends​ State<HomePage> {
 String​ _connectionStatus = ​'Unknown'​;
  IconData _connectionIcon;
 String​ _batteryStatus = ​'Unknown'​;
  IconData _batteryIcon;
  Color _connectionColor = Colors.deepOrange;
  Color _batteryColor = Colors.deepOrange;

Getting the Battery and Connectivity Data: Asynchronous Programming Using Streams

Since the data we are going to be showing could change at any time, the packages allow the data to be used in the form of Streams, which allow your code to listen for changes in the data and define the actions that need to be taken using the new data when it changes.

In this case, we want to change the state of the widget by changing the strings and icons describing the connectivity and battery state.

We can do that using the following code:

StreamSubscription<ConnectivityResult> _connSub;
 StreamSubscription<BatteryState> _battSub;
 
 @override
 void​ ​initState​() {
 super​.initState();
 
_connSub = Connectivity()
  .onConnectivityChanged
  .listen(( ConnectivityResult res) async {
  setState(() {
switch​(res) {
 case​ ConnectivityResult.mobile:
  _connectionStatus = ​'Mobile Data'​;
  _connectionIcon = Icons.sim_card;
  _connectionColor = Colors.red;
 break​;
 case​ ConnectivityResult.wifi:
  _connectionStatus = ​'Wi-Fi'​;
  _connectionIcon = Icons.wifi;
  _connectionColor = Colors.blue;
 break​;
 
 
 case​ ConnectivityResult.none:
  _connectionStatus = ​"No Connection"​;
  _connectionIcon = Icons.not_interested;
  _connectionColor = Colors.black;
  }
  });
  });
 
_battSub = Battery()
  .onBatteryStateChanged
  .listen((BatteryState res) async {
  setState(() {
 switch​(res) {
 case​ BatteryState.charging:
  _batteryStatus = ​'Charging'​;
  _batteryIcon = Icons.battery_charging_full;
  _batteryColor = Colors.blueAccent;
 break​;
 case​ BatteryState.full:
  _batteryStatus = ​'Full'​;
  _batteryIcon = Icons.battery_full;
  _batteryColor = Colors.green;
 break​;
 case​ BatteryState.discharging:
  _batteryStatus = ​'In Use'​;
  _batteryIcon = Icons.battery_alert;
  _batteryColor = Colors.redAccent;
  }
  });
  });
 }

These two lines are used to define the StreamSubscriptions we’ll be using in our app. subscriptions are used to run some code when the data returned by a Stream changes.

We are calling the Connectivity constructor to get an object and listen on its member onConnectivityChanged Stream, which, like all Streams, has a listen member function, which takes as a positional argument the callback function to be called when the connectivity changes, which will usually be a call to setState, since in most apps a change in a Stream means that the app’s UI needs to be updated.

In case you’re not familiar with it, the usage of a switch statement is explained in Switch. In this instance, we’re using it to set different strings, icons, and colors for each connection and battery status.

This is the same as what we’ve seen for the connectivity status, but for the battery status.

Since this code is doing a lot of different things, we’ll break this down and explain each part.

Disposing of the StreamSubscriptions

For each subscription there needs to be an entry to the dispose method to dispose of the subscription when it’s not needed anymore. StreamSubscriptions have a cancel method, which does exactly that. Since State classes need to override their superclass’ dispose method (which is the method that runs when that State isn’t needed anymore, which is when the StatefulWidget isn’t being rendered anymore), they need to call super.dispose:

 @override
 dispose() {
 super​.dispose();
  _connSub.cancel();
  _battSub.cancel();
 }

You can find out more about Streams in Streams and StreamSubscriptions.

Defining the App’s UI

The build method will be the following:

 @override
 Widget ​build​(BuildContext context) {
 return​ Scaffold(
  backgroundColor: Theme.of(context).backgroundColor,
  appBar: AppBar(
  title: Text(widget.title),
  ),
  body: Column(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: <Widget>[
  Row(
  children: <Widget>[
  Icon(_connectionIcon, color: _connectionColor, size: 50.0),
  Text(
 "Connection:​​ ​​$_connectionStatus​​"​,
  style: TextStyle(
  color: _connectionColor,
  fontSize: 40.0,
  ),
  ),
  ],
  ),
  Row(
  children: <Widget>[
  Icon(_batteryIcon, color: _batteryColor, size: 50.0),
  Text(
 "Battery:​​ ​​$_batteryStatus​​"​,
  style: TextStyle(
  color: _batteryColor,
  fontSize: 40.0,
  ),
  ),
  ]
  ),
  ],
  ),
  );
 }

The app’s body is a Column, with the mainAxisAlignment set to MainAxisAlignment.spaceAround so the widgets occcupy the entire body, instead of being stacked closely on top:

 body: Column(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: <Widget>[
  Row(
  children: <Widget>[
  Icon(_connectionIcon, color: _connectionColor, size: 50.0),
  Text(
 "Connection:​​ ​​$_connectionStatus​​"​,
  style: TextStyle(
  color: _connectionColor,
  fontSize: 40.0,
  ),
  ),
  ],
  ),
  Row(
  children: <Widget>[
  Icon(_batteryIcon, color: _batteryColor, size: 50.0),
  Text(
 "Battery:​​ ​​$_batteryStatus​​"​,
  style: TextStyle(
  color: _batteryColor,
  fontSize: 40.0,
  ),
  ),
  ]
  ),
  ],
 ),

The Column contains two Rows, one showing the connection state, and one showing the battery state.

Showing the States

The connection state will be shown using a Row to show both the string and the icon of the color we set when the state changes:

 Row(
  children: <Widget>[
  Icon(_connectionIcon, color: _connectionColor, size: 50.0),
  Text(
 "Connection:​​ ​​$_connectionStatus​​"​,
  style: TextStyle(
  color: _connectionColor,
  fontSize: 40.0,
  ),
  ),
  ],
 ),
 Row(
  children: <Widget>[
  Icon(_batteryIcon, color: _batteryColor, size: 50.0),
  Text(
 "Battery:​​ ​​$_batteryStatus​​"​,
  style: TextStyle(
  color: _batteryColor,
  fontSize: 40.0,
  ),
  ),
  ]
 ),

The result is that each status is represented by a different Icon and string of a different color for each battery status:

images/Packages/charging.png
images/Packages/full.png
images/Packages/inuse.png

and for each connectivity status:

images/Packages/mobiledata.png
images/Packages/noconnection.png
images/Packages/wifi.png
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset