Get Informed out of Data

Full width home advertisement

Raspbian

DataScience

Post Page Advertisement [Top]

Need of Flutter inside Embedded Development

Need of Flutter inside Embedded Development

Flutter is an interesting tool In terms of cross platform. Is general cross platform apps are more focused on Web android and IOS but the thing is these are more the differentiation of architecture which comes into picture For each Host system.


 In this case, flutter solves an interesting problem in terms of converting the whole architecture into a desktop environment.


Now the issue becomes more Centralized towards solving the problem in terms of the screen space or else the working screen.So architecture needs a tool chain That would convert the source code to be built into the code with platform required dependencies.


Flatter has more support on the linux based OS, especially ubuntu. This will solve an extreme problem, for example Ubuntu supports more architectures for devices considering general laptops, mobile of ARM and RISC-V.


As the embedded devices will enter into the microservices architecture where the client devices will have more  data services to show. A desktop app should enable a custom full screen app that will help create something like a kiosk system where the user can interact with easily.


This also enables us to work on a single source code where we could interact with various devices. In terms of API creation, it helps because at the server side we are just going to handle things based on user requirement then device requirement.


So this is an initial post for making a strong recommendation towards learning flutter in the upcoming days to create an ecosystem of devices where our app can fit in perfectly.


Also the date of flow between the server side and client side will be more interactive and also visually appealing in terms of UI between the systems.


For a Embedded Developer, most of the programming use case would be handling the Registers / Addresses that are built into the microcontroller or peripherals attached.Flutter’s solution to handle the problem in design concept to consider each item present in the screen as a widget is more similar to the each register available on the hardware.




Coming into Flutter App Development - constructing code has two major Units - whatever the UI design might be, data handling will eventually make the app’s primary requirement.


  • Stateless Widget

  • Stateful Widget


A stateless widget cannot change its state during the runtime. That means a stateless widget cannot be recreated while the app is in action.


For that reason, the appearance and properties remain unchanged throughout the lifetime of the widget.


A stateful widget is used when data variables change dynamically during runtime, also can be recreated themselves multiple times while the app is running.


Deep down these two options are the core of the programming possibilities which we are more aware of.


  • Stack

  • Heap


Stack are things which are arranged in one above one but also it won’t change with respect to time but that needs to be destroyed before recreating it.


Whereas  Heap will act as the same pointer which has different data that’s being altered at the run-time.

  • Stack = Stateless Widget

  • Heap = Stateful Widget


Also Stateless Widget and Stateful Widget can be compared to compile time and run-time environments which helps in cache code regions in perspective of the app management.


Kindly, let me know your views on making these comparisons which you might state as illogical things to compare.


The Picture here is more clear - we need to create a data flow considering the fact each screen layout is built on top of some other screen. So, a better pseudo code for the entire app will be mandatory where each app logic will flow through the requests.


Here are the few flutter extensions you must have for getting started in flutter.

Obviously the first one  will be the Dart,


Dart: Extends VS Code with support for the Dart programming language


Flutter: Adds support for effectively editing, refactoring, running, and reloading Flutter apps


Pubspec Assist: This extension allows you to search for packages without having to leave the editor and then adds them to the pubspec.yaml file


Awesome Flutter Snippets: This extension is a collection of commonly used Flutter classes and methods. It helps in code generation for stateless and stateful widgets.


Interoperability is an interesting prospect of Flutter as the amount of plugins available is making it wide open to make it a visual programming tool than a common statically typed programming.


For making it visual - we need to know concept of flutter logics,


Widgets will be in class form.


Let's get into the technical details of useful snippet for Flutter

Widget

A widget is the basic type of controller in Flutter Material. There are two types of basic Widget we can extend our classes: StatefulWidget or StatelessWidget.

Stateful

StatefulWidget are all the widget that interally have a dynamic value that can change during usage. It can receive an input value in the constructor or reference to functions. You need to create two classes like:

class BasePage extends StatefulWidget {

  State<StatefulWidget> createState() {

    return _BasePageState();

  }

}


class _BasePageState extends State<BasePage> {

  int _value = 0;

  

  void _increment() {

    setState(() {

      _value++;

    });

  }

}

When you are going to update the value you need to wrap it in setState(() {}) function.

If you want to mimic the viewDidLoad of iOS you can use in the State class this call

@override

void initState() {

  super.initState()

  // add here what to do, e.g. fetch data from remote

}

Instead if you want get triggered on status update:

@override

void didUpdateWidget(CurrentType oldWidget) {

  super.didUpdateWidget(oldWidget);

  // here you can check value of old widget status and compare vs current one

}

Stateless

StatelessWidget are components that are rendered and keep that value. A refresh by a parent is needed to update the content. It can receive a value from the constructor.

Model

Dart has class a nice way to create an init is using the approach like { this.param, this.param2 }.

class New {

  final String element;

  final double number;

  

  New({ this.element, this.number });

}

In order to have mandatory params you need to include flutter/material.dart so you can transform you class to

class En {

  final String element;

  final double number;

  

  New({ @required this.element, @required this.number });

}

If you wrap a param between [] that param is optional instead.

Scope Model

Is a good way to share data within the app in an unique place, accessibile in any other class. Scope model gives you a way to keep the state of the model created above. So once scope_model has been imported you can create the model like:

class EnModel extends Model {

}

When you work with an item, it is better to avoid passing back the list you are using to manage the item internally, better to use a copy of that. So we have to use a getter.

class EnModel extends Model {

  List<String> _item = [];

  List<String> get item {

    List.from(_item);

  }; 

}

In order later to use that, in the widget build you have to:

return ScopeModelDescendant<EnModel>(builder: (BuildContext context, Widget child, EnModel model){

  return _buildWidget(model.item);

},);

Each time the build is called the data is read back from state.

We can force the refresh of a build function using the notifyListeners().

If you have more than one model, better to create a main.dart model like:

class MainModel extends Model with New, EnModel {}

In order to avoid calling this in all the classes, we can easily wrap our MaterialApp in ScopeModel<EnModel>(child: MaterialApp[...], model: EnModel()).

So all the children of MaterialApp will have access to the EnModel structure.

In order to have access you will still have to use ScopeModelDescendant to wrap the Widget that will use that as above.

UI

Icon & Splashpage

https://flutter.io/assets-and-images/#updating-the-launch-screen

Screen Size

Size(MediaQuery.of(context).size.width

Colors & Themes

You can acces colors using Colors.white. Each color has an extra parameter withOpacity() you can use to set the opacity.

You can use theme colors using Theme.of(context).accentColor

Styling

You can add extra style (background color, rounded corners, etc) to a widget using DecoratedBox.

DecorationBox(decoration: BoxDecoration());

Layout

ListView acts like a good stack for putting elements in columns. If it contains only an object, use SingleChildScrollView.

Either Column and Row are ok but don't support scroll. If you want to widget in a column/row to take as much space as possible wrap it in Expanded. Flexibility is also available and you can provide which priority on weight the widget will have. Both Expanded and Flexible accept a flex param, where you can pass a weight.

SizeBox is a widget with fixed size, it is useful e.g. to add a simple margin between widgets.

Container is a box where you can add your Widget and set some params like margin, padding, color, decoration, etc.

Size

MediaQuery is a powerful tool to make adaptive UI according to device features (e.g. screen size, orientation).

MediaQuery.of(context)

Navigation

Route to another page without back (eg android final)

Navigator.pushReplacement(

                  context,

                  MaterialPageRoute(

                    builder: (BuildContext context) => Class(

                          param: value,

                        ),

                  )),

Route to other page with back

Navigator.push(

                  context,

                  MaterialPageRoute(

                    builder: (BuildContext context) => Class(

                          param: value,

                        ),

                  )),

Back (Basic)

Navigator.pop(context);

Back (Passing data)

Navigator.pop(context, back_value);

Action after navigation

In certain cases it is useful to trigger an action when a navigation is called,you can do that by combining a then((_) {}) function in the pipe of the navigator.

Also edit Navigator.push<type>[…].then((type value) {}) adding future type.

Sidebar

Add left drawer

In the drawer we can list several entries, each of those can have (or not) an Icon.

New Scaffold(drawer: 

Drawer(child: 

Column(children: <Widget>[ 

AppBar(title: Text(‘Choose’), AutomaticallyImplyLeading: false ), 

ListTile(

leading: Icon(Icons.list),

title: Text(’Some Text’), 

onTap: () {} 

) ])

Add right drawer

New Scaffold(endDrawer:

Tabs

Body of Scaffold needs to have TabBarView to manage switch between tabs contents. The number in length is mandatory to be the same as the items in the TabBarView and TabBar tabs.

The pages have not to be Scaffold Widget, but directly the body because they are in the TabBarView that already has a Scaffold.

Add drawer with tab on top like Android

DefaultTabController(length: 2, child: Scaffold( body: TabBarView(),  appBar: AppBar(bottom: TabBar(tabs: <Widget>[ Tab(icon:, text:) ])

Add drawer with tab on Button like iOS

DefaultTabController(length: 2, child: Scaffold( body: TabBarView(), bottomNavigationBar:  TabBar(tabs: <Widget>[ Tab() ])

Routing

Add in main MaterialApp a new key route that supports a map.

routes: {

“/“:  (BuildContext context) => HomeClass()

“/admin”: (BuildContext context) => AdminClass()

}

Then in every part of the app you can call .pushReplacementNamed(‘/admin’, context); Note: If you set “/“ you have to remove the home value in the material app or an error will raise.

Pass value in routes

Instead of using routes, you need to use the onGenerateRoutes key. If a route is already defined in routes it will raise an error.

onGenerateRoutes: (RouteSettings settings) {

final List<String> pathElements = settings.name.split(“/“);


if(pathElements[0] != “”) {

return null;

}

if(pathElements[1] == ‘product’) {

final int index = int.parse(pathElements[2]);

return MaterialPageRoute<bool>(builder: (BuilderContext context) => ProductPage(_products[index]))

}

return null;

}

In this scenario the main file has to be converted in StatefulWidget to centralize where the variables are stored. In the example I set MaterialPageRoute to return a bool, but we can se that to every other type.

Then you can call .pushNamed(context, ‘/product/‘ + index.toString())

Also there’s a fallback for the unKnown Route.

Alert

showDialog using an AlertDialog as Widget.

showDialog(context: context, builder: (BuilderContext context) {

return AlertDialog(

title: Text(),

content: Text(),

actions: <Widget> [

FlatButton(child: Text(), onPressed: () {

Navigator.pop(context); // close the dialog

})

]

}

Modal

showModalButtonSheet(context: context, builder: (BuilderContext context) {

return Center(

child: Text()

);

}

Textfield

In order to add a title we need to use InputDecoration(labelText:).

In order to set a custom keyboard use InputDecoration(keyboardType: (true|false)).

In order to handle password use InputDecoration(obscureText: (true|false).

In order to get the value onChanged: (value) {}. In order to monitor the value you need a StatefulWidget.

AppBar

AppBar components allow you to set title, back and actions for the status bar. title contains the title for the widget. actions is an array of widgets that stay on the right.

Gesture

You can turn every widget with an action wrapping inside GestureDetector.

Keyboard

If you need to hide an open keyboard you need to use FocusScope.

FocusScope.of(context).requestFocus(FocusNode());

So basically you fake the current focus node a new one not connected to any form/textarea.






No comments:

Post a Comment

Bottom Ad [Post Page]