Mobile application course
1- CATEGORIES OF APPLICATION DEVELOPMENT
An application can be defined as a collection of programs that satisfy certain specific
requirements towards resolving a problem. Hence an application can be considered
as a solution or collection of solutions to related problems. This solution or solutions
could target and reside on specific platform or on different platforms, from a
hardware or operating system perspective [4]. Before an application is ready for use,
it passes through various steps and processes which can collectively be called
application development lifecycles. Application development lifecycle include the
following steps:
Planning and preparing requirements: include identifying the need for the
application, considering existing applications as a solution, specifying user
target group, specifying target platform, considering features of existing
applications.
Analysis: include defining and documenting functional requirements for the
application and predicting potential problems that may be faced during the
lifecycle of the application.
Design: include defining and documenting application features, components,
and parts. It also defines the integration of different parts of the application, their
use, and the use of the application in general.
Construction (Coding): programming the application as per the guidelines of the
verified requirements and design.
Testing: trying out the application primarily for finding pitfalls and errors.
Testing should also confirm if specified requirements and design are met.
Implementation (production): making the application ready for use after all
functionalities and requirements have been met. It includes preparation of
documentation for application usage and operational procedures.
Support (Maintenance): include user experience monitoring, changes, and
improvements of the application.
Iman Qays Abduljaleel/university of basrah
Although, factors such as, application size and budget, clarity and specificity of
requirements, size of development team and competence of each team member,
changes in requirements, project time span, determine whether or not these lifecycle
steps should strictly be followed, they are generally used as standard lifecycle steps
in application development[4,5]. The execution of these lifecycle steps may vary
from organization to organization or even from team to team in an organization. In
general, application development lifecycle steps can be accomplished by using most
common application development methodologies such as waterfall development,
agile development, and rapid application development (RAD).
2- MOBILE APPLICATION DEVELOPMENT APPROACHES
Nowadays mobile applications are directly involved in our day to day lives. There
are ranges of mobile applications we use to facilitate our daily activities such as
mobile payment, online shopping, transportation applications, text, and video
messaging applications to mention few. There exist millions of apps available for us
in different mobile application stores such as Google play Store and App store. The
ever-increasing mobile application usage is driving businesses and solo developers
to invest their time and money targeting these users. Such strong demand has led
businesses and developers to find new ways of mobile application development to
target massive amounts of users with less development cost for applications. The
diverse nature of mobile platforms has been the main constraint for businesses and
developers to find new ways of mobile application development rather than
following cost inefficient platform-specific mobile application development.
Furthermore, mobile application development needs frequent improvements and
adaptations to meet the fast-changing usability challenges. Handheld device
manufacturers increasingly adapt new designs which range from changing device
screen sizes to improvements in device capabilities, hence a mobile application must
adapt to all these new changes to increase its usage. Although there exist millions of
mobile applications in different applications markets, they can generally be
classified into three categories as platform specific applications, responsive or
adaptive web applications and cross-platform native applications [19,20].
2-1 Platform-specific native applications
Iman Qays Abduljaleel/university of basrah
Platform specific or Native application is a software developed to a targeted platform
based on the programming language that specific platform supports. It is developed
using platform specific SDK and frameworks and its existence is tied to that specific
platform. For instance, an iOS application is developed with Objective C or Swift
using the iOS SDK and the APIs provided by Apple and uses platform provided
elements for rendering the application UI. Native applications are sometimes called
embedded applications to signify that these kinds of applications ensure an in-depth
integration with the mobile operating system. Applications developed by using
platform specific languages allow accessing device specific capabilities such as
video and audio capabilities, Global Positioning System (GPS), native calendars etc.
Native applications could provide the best performance possible and development is
supported by platform friendly integrated development environments (IDEs). These
IDEs are designed to provide best development experiences such as debugging the
application and contain tools that help perform memory and performance analysis.
The two most widely used application platforms are Google's Android and Apple's
iOS. Applications native to android can be written by using Java or Kotlin
programming languages, on the most widely used development IDE, Android
Studio. Android Studio provides ranges of benefits to developers. It helps developers
to be more productive during the development process, by providing built-in support
for Google services, such as Firebase Cloud Messaging, Google application engine.
It eases application development for different devices including smartphones,
wearables, and Android TV. Android Studio also provides the ability to download
an android application package (.apk) file and publish it to Google play store related
to the developer's account. Whereas, applications native to iOS can be written using
objective C or Swift programming languages, on the primarily used IDE, XCode.
Like Android, XCode provides a range of development benefits to developers
including the ability to publish application packages to the Apple’s app store. Other
existing mobile platforms and their primary development technologies are shown in
Table 2 [16,17].
Native applications developed for specific platforms are mainly available for
downloads from a platform dedicated system, such as Apple Store and Google Play
Store. Figure 2 demonstrates native application development.
Iman Qays Abduljaleel/university of basrah
Although platform-specific mobile applications provide higher performance and
utilization of native device capabilities, their variety make development and
Iman Qays Abduljaleel/university of basrah
maintenance costs higher. Platform-specific application code cannot be reutilized for
other platforms, development needs dedicated resources and relevant platform-
specific competency.
2-2 Responsive web applications
In recent years, emerging web technologies allow businesses and developers to
develop responsive web applications that work seamlessly regardless of the type and
screen size of a device. Traditionally businesses used to follow pixel-perfect design
approaches to develop their web applications. Pixel-perfect web design is performed
by creating mock-ups of a web page using tools like Photoshop. Developers then
program the design to fit a standard web browser. Often these pixel-perfect designed
web applications would not fit to browser screens sizes that are not primarily
considered in the design. Pixel-perfect design approaches became a bottleneck as the
variety of screen sizes grew. Hence, a responsive web design approach has emerged
to solve this problem [21].
Responsive web applications that run on mobile platforms depend on web
technology standards and browser support of mobile platforms. The most widely
used web application architecture divides the whole application into three layers
such as presentation, logic, and data layers. The presentation layer is solely
responsible for rendering the user interface. Whereas the logic layer contains
different application logics such as server-side programs and connections to the data
layer for data storage and retrieval. The data layer on the other hand is responsible
for persisting data. Although the logic layer can be implemented using different
programming languages (Java, Python, Nodejs etc.), the presentation layer is mainly
dependent on web technologies such as JavaScript, HTML and CSS. It is mostly on
the presentation layer that the responsiveness of a web application is implemented.
Generally responsive web applications try to fit different screen sizes by using web
design techniques such as, flexible grid-based layout, expandable images, and media
queries. Flexible grids are mainly designed by using relative percentage unit CSS
styles rather than absolute pixel unit styles. Media query is a web designing
technique which defines rules to include CSS properties and values when a certain
condition fulfills. It helps to apply different CSS styles in response to media type
and screen sizes. Expandable images can be achieved by setting the width property
of an image (100%) and the height property of an image to auto. This way the image
will be responsive, and it can easily scale up and down according to the screen size.
Iman Qays Abduljaleel/university of basrah
The code snippet in Figure 3 illustrates how responsiveness can be applied to web
applications.
Among the main advantages of responsive web applications is the ability to reutilize
code. They require less platform-specific adaptations and they can easily be
deployed to run on browsers regardless of the platform. On the contrary, responsive
web apps are less attractive because they do not give native app-like feels, client-
server interaction has higher latency than native apps, they have limitations on
accessing native device capabilities. Moreover, they pose security risks since code
is executed through a browser [21,22,23].
2-3 Cross-platform applications
In the world today, there exist a variety of smartphones and tablets which run
different platforms. These platforms have their own specific programming language,
set of APIs and application development and distribution environments. Developing
an application specifically targeting an individual platform requires dedicated
resources with platform specific development competency. A business which wants
to target multiple platforms should therefore dedicate multiple resources with
platform specific competence for the same application. This results in increasing
Iman Qays Abduljaleel/university of basrah
development cost and time for the application. Diversity of handheld device
platforms has long been a bottleneck for businesses to target as many application
users as possible with viable application development and maintenance cost. Issues
like this have given a rise to the cross-platform applications which can be deployed
and run on different platforms by reutilizing a single application code base.
Cross-platform applications are generally developed by using platform independent
frameworks which provide development APIs in various programming languages.
The application utilizes the provided APIs to map UI elements, to persist data and
to wire business logics. This application code is then compiled to a native code by
using a technique called cross-compilation. Cross-compilations is a way of
transforming an application code into platform-specific executable code with the
help of a cross-compiler. This executable code is then deployed and executed
natively on the targeted platform.
Generally cross-platform applications which are not responsive-web applications
can be classified as hybrid web applications, interpreted applications and cross-
compiled applications [16,17,24,25].
Hybrid web application: hybrid web application brings together web
technologies and native development approaches. The approach utilizes the
browser engine in the device and synchronizes the HTML content in the native
web containers such as, WebView in android, UIWebView in iOS, platforms.
These web containers have access to platform-specific functionalities through
APIs. Hybrid applications reutilize code for various platforms and provide
access to native device capabilities, however user experiences might be
unpleasant due to lack of usage of native UI components and slowness of the
app related to loading web containers. Unlike responsive web applications which
are accessed via web browsers, hybrid applications are distributed through app
stores.
Interpreted application: This kind of applications might use common
programming languages to develop application user interface, however code
must be interpreted to an equivalent platform native code at runtime to access
platform specific APIs. Access to platform specific APIs allow interpreted
applications to use native UI elements as a result user experience is generally
Iman Qays Abduljaleel/university of basrah
better than hybrid web applications. On the contrary, there are performance
issues due to code conversion during runtime.
Cross-compiled application: For this kind of application, code is compiled to
platform specific, high-performance native code with the help of cross compiler.
Cross-compiled applications can provide native feels and performances because
they have access to all native UI elements and APIs. However, different platform
specific tweaks and configurations might be necessary to access device
capabilities such as device audio and video, native calendar applications, device
information etc. Cross-compiled applications can be developed with the help of
cross-platform mobile application frameworks such as React Native, Flutter etc.
The characteristics of React Native and Flutter are discussed in subsequent
sections.
When it comes to development, cross-platform applications can be developed by
using different tools. These tools can be generally grouped as libraries, frameworks,
and platforms, depending on the functionality they provide [24].
Library: usually optimized, self-contained collection of implementations which
provide specific functionality such as graphics or UI. A library provides a well-
defined interface to invoke functionalities through independent programs.
Libraries should coexist with other libraries to make a fully functional mobile
application.
Iman Qays Abduljaleel/university of basrah
Framework: a collection of libraries, software components and architectural
guidelines which provide generic functionality. Generally, frameworks contain
different libraries, configuration files and APIs for building a fully functional
mobile application.
Platform: an integrated development environment which composed a set of
frameworks, tools and services for building and distributing mobile applications.
Platforms usually offer functional tools for debugging, configuring,
documenting, and automating an application.
3- Introduction to Flutter
In general, developing a mobile application is a complex and challenging task. There
are many frameworks available to develop a mobile application. Android provides a
native framework based on Java language and iOS provides a native framework
based on Objective-C / Shift language.
However, to develop an application supporting both the OSs, we need to code in two
different languages using two different frameworks. To help overcome this
complexity, there exists mobile frameworks supporting both OS. These frameworks
range from simple HTML based hybrid mobile application framework (which uses
HTML for User Interface and JavaScript for application logic) to complex language
specific framework (which do the heavy lifting of converting code to native code).
Irrespective of their simplicity or complexity, these frameworks always have many
disadvantages, one of the main drawback being their slow performance.
In this scenario, Flutter – a simple and high performance framework based on Dart
language, provides high performance by rendering the UI directly in the operating
system’s canvas rather than through native framework.
Flutter also offers many ready to use widgets (UI) to create a modern application.
These widgets are optimized for mobile environment and designing the application
using widgets is as simple as designing HTML.
To be specific, Flutter application is itself a widget. Flutter widgets also supports
animations and gestures. The application logic is based on reactive programming.
Widget may optionally have a state. By changing the state of the widget, Flutter will
automatically (reactive programming) compare the widget’s state (old and new) and
render the widget with only the necessary changes instead of re-rendering the whole
widget.
Iman Qays Abduljaleel/university of basrah
4- Features of Flutter
5- Advantages of Flutter
Flutter offers many more advantages as mentioned below:
Dart has a large repository of software packages which lets you to extend the
capabilities of your application.
Developers need to write just a single code base for both applications (both
Android and iOS platforms). Flutter may to be extended to other platform as
well in the future.
Flutter needs lesser testing. Because of its single code base, it is sufficient if
we write automated tests once for both the platforms.
Flutter’s simplicity makes it a good candidate for fast development. Its
customization capability and extendibility makes it even more powerful.
With Flutter, developers has full control over the widgets and its layout.
Flutter offers great developer tools, with amazing hot reload.
6- Disadvantages of Flutter
Despite its many advantages, flutter has the following drawbacks in it:
Since it is coded in Dart language, a developer needs to learn new language
(though it is easy to learn).
Modern framework tries to separate logic and UI as much as possible but, in
Flutter, user interface and logic is intermixed. We can overcome this using
smart coding and using high level module to separate user interface and logic.
Flutter is yet another framework to create mobile application. Developers are
having a hard time in choosing the right development tools in hugely
populated segment.
Iman Qays Abduljaleel/university of basrah
7- Installation in Windows
In this section, let us see how to install Flutter SDK and its requirement in a windows
system.
Iman Qays Abduljaleel/university of basrah
8- Create flutter application
Let us create a simple Flutter application to understand the basics of creating
a flutter application in the Android Studio.
Iman Qays Abduljaleel/university of basrah
Iman Qays Abduljaleel/university of basrah
Iman Qays Abduljaleel/university of basrah
Iman Qays Abduljaleel/university of basrah
Iman Qays Abduljaleel/university of basrah
Step 7: Replace the dart code in the lib/[Link] file with the below code:
import 'package:flutter/[Link]';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: const Center(
child: Text('Hello World'),
),
),
);
}
}
Iman Qays Abduljaleel/university of basrah
Iman Qays Abduljaleel/university of basrah
9- the architecture of the Flutter framework
The core concept of the Flutter framework is In Flutter, Everything is a
widget. Widgets are basically user interface components used to create the
user interface of the application.
In Flutter, the application is itself a widget. The application is the top- level
widget and its UI is build using one or more children (widgets), which again
build using its children widgets. This composability feature helps us to create
a user interface of any complexity.
For example, the widget hierarchy of the hello world application (created in
previous chapter) is as specified in the following diagram:
Here the following points are worth notable:
MyApp is the user created widget and it is build using the Flutter native
widget, MaterialApp.
MaterialApp has a home property to specify the user interface of the home
page, which is again a user created widget, MyHomePage.
MyHomePage is build using another flutter native widget, Scaffold.
Scaffold has two properties – body and appBar.
body is used to specify its main user interface and appBar is used to specify
its header user interface.
Iman Qays Abduljaleel/university of basrah
Header UI is build using flutter native widget, AppBar and Body UI is build
using Center widget.
The Center widget has a property, Child, which refers the actual content and
it is build using Text widget.
UNDERSTANDING WIDGET LIFECYCLE EVENTS
In programming, you have different lifecycle events that usually happen in a linear
mode, one after another as each stage is completed. In this section, you’ll learn the
widget lifecycle events and their purpose.
To build the UI, you use two main types of widgets, StatelessWidget and
StatefulWidget. A stateless widget is used when the values (state) do not change,
and the stateful widget is used when values (state) change. In Chapter 2, “Creating
a Hello World App,” you’ll learn in detail when to use a StatelessWidget or a
StatefulWidget. Each stateless or stateful widget has a build method with a
BuildContext that handles the location of the widget in the widget tree. The
BuildContext objects are actually Element objects, an instantiation of the Widget at
a location in the tree.
The StatelessWidget Lifecycle
A StatelessWidget is built based on its own configuration and does not change
dynamically. For example, the screen displays an image with a description and will
not change. The stateless widget is declared with one class. The build (the UI
portions) method of the stateless widget can be called from three different scenarios.
It can be called the first time the widget is created, when the widget’s parent changes,
and when an InheritedWidget has changed. The following sample code shows a
StatelessWidget base structure, and Figure 1.1 displays the widget’s lifecycle.
class JournalList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container();
}
}
Iman Qays Abduljaleel/university of basrah
The StatefulWidget Lifecycle
A StatefulWidget is built based on its own configuration but can change
dynamically. For example, the screen displays an icon with a description, but values
can change based on the user’s interaction, like choosing a different icon or
description. This type of widget has a mutable state that can change over time. The
stateful widget is declared with two classes, the StatefulWidget class and the State
class. The StatefulWidget class is rebuilt when the widget’s configuration changes,
but the State class can persist (remain), enhancing performance. For example, when
the state changes, the widget is rebuilt. If the StatefulWidget is removed from the
tree and then inserted back into the tree sometime in the future, a new State object is
created. Note that under certain circumstances and restrictions, you can use a
GlobalKey (unique key across entire app) to reuse (not re-create) the State object;
however, global keys are expensive, and unless they’re needed, you might want to
consider not using them. You call the setState() method to notify the framework that
this object has changes, and the widget’s build method is called (scheduled). You
would set the new state values inside the setState() method. In Chapter 2, you’ll learn
how to call the setState() method.
The following example shows a StatefulWidget base structure, and Figure 1.2
displays the widget’s lifecycle. You have two classes, the JournalEdit
StatefulWidget class and the _JournalEditState class.
class JournalEdit extends StatefulWidget {
@override
_ JournalEditState createState() => _ JournalEditState();
}
class _JournalEditState extends State<JournalEdit> {
@override
Widget build(BuildContext context) {
return Container();
}
}
Iman Qays Abduljaleel/university of basrah
You can override different portions of the StatefulWidget to customize and
manipulate data at different points of the widget lifecycle. Table 1.1 shows some of
the stateful widget main overrides, and the majority of the time you’ll use the
initState(), didChangeDependencies(), and dispose() methods. You’ll use the build()
method all of the time to build your UI.
Iman Qays Abduljaleel/university of basrah
UNDERSTANDING THE WIDGET TREE AND THE ELEMENT TREE
In the previous section, you learned that widgets contain the instructions to create
the UI, and when you compose (nest) widgets together, they create the widget tree.
The Flutter framework uses the widgets as the configurations for each element that
is mounted (rendered) on the screen. The mounted elements displayed on the screen
create the element tree. You now have two trees, the widget tree that has the widget
configurations and the element tree that represents the rendered widgets on the
screen (Figure 1.3).
When the application starts, the main() function calls the runApp() method, usually
taking a StatelessWidget as the argument, and is mounted as the root element for the
Iman Qays Abduljaleel/university of basrah
application. The Flutter framework processes through all of the widgets, and each
corresponding element is mounted.
The following is sample code that starts a Flutter application, and the runApp()
method inflates the MyApp StatelessWidget, meaning the main application itself is
a widget. As you can see, just about everything in Flutter is a widget.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter App',
theme: ThemeData(
primarySwatch: [Link],
),
home: MyHomePage(title: 'Home'),
);
}
}
Elements have a reference to the widget and are responsible for comparing the
widget differences. If a widget is responsible for building child widgets, then
elements are created for each child widget. When you see the use of BuildContext
objects, they are the Element objects. To discourage direct manipulation of the
Element objects, the BuildContext interface is used instead. The Flutter framework
uses BuildContext objects to discourage you from manipulating the Element objects.
In other words, you’ll be using widgets to create your UI layouts, but it’s good to
know how the Flutter framework is architected and how it works behind the scenes.
As noted earlier, there is a third tree called the render tree that is a low-level layout
and painting system that inherits from the RenderObject. The RenderObject
computes and implements the basic layout and paint protocols. You won’t need to
interact directly with the render tree, however, and will be using the widgets.
USING THEMES TO STYLE YOUR APP
Iman Qays Abduljaleel/university of basrah
The theme widgets are a great way to style and define global colors and font styles
for your [Link] are two ways to use theme widgets—to style the look and feel
globally or to style just a portion of the app. For instance, you can use themes to
style the color brightness (light text on a dark background or vice versa); the primary
and accent colors; the canvas color; and the color of app bars, cards, dividers,
selected and unselected options, buttons, hints, errors, text, icons, and so on. The
beauty of Flutter is that most items are widgets, and just about everything is
customizable. In fact, customizing the ThemeData class allows you to change the
color and typography of widgets.
Using a Global App Theme
import 'package:flutter/[Link]';
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
const appName = 'IMAN QAYS';
return MaterialApp(
title: appName,
theme: ThemeData(
// Define the default brightness and colors.
brightness: [Link],
primaryColor: [Link][800],
// Define the default font family.
fontFamily: 'Georgia',
// Define the default `TextTheme`. Use this to
specify the default
// text styling for headlines, titles, bodies
of text, and more.
Iman Qays Abduljaleel/university of basrah
textTheme: const TextTheme(
headline1: TextStyle(fontSize: 72.0,
fontWeight: [Link]),
headline6: TextStyle(fontSize: 36.0,
fontStyle: [Link]),
bodyText2: TextStyle(fontSize: 14.0,
fontFamily: 'Hind'),
),
),
home: const MyHomePage(
title: appName,
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
const MyHomePage({Key? key, required [Link]}) :
super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Container(
color:
[Link](context).[Link],
child: Text(
'Text with a background color',
style:
[Link](context).textTheme.headline6,
),
),
),
floatingActionButton: Theme(
Iman Qays Abduljaleel/university of basrah
data: [Link](context).copyWith(splashColor:
[Link]),
child: FloatingActionButton(
onPressed: () {},
child: const Icon([Link]),
),
),
);
}
}
Examples codes
1-sizing an image
import 'package:flutter/[Link]';
void main() { runApp(Center(
child: Container(
height: 300.0,
width: 200.0,
child:
[Link]("[Link]
[Link]"),
),
),
);
}
2-insert text
import 'package:flutter/[Link]';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: [Link],
),
),
Iman Qays Abduljaleel/university of basrah
);
}
3-insert text in X,Y
import 'package:flutter/[Link]';
void main() {
runApp(
Center(
child: Container(
height: 400.0,
width: 200.0,
child: Text(
'Hello, world!',
textDirection: [Link],
),
),
),
);
}
4- Placeholder
import 'package:flutter/[Link]';
void main() {
runApp(
Center(
child: Container(
height: 200.0,
width: 200.0,
child: Placeholder(),
),
),
);
}
5- Column
import 'package:flutter/[Link]';
void main() {
runApp(
Center(
child: Column(
Iman Qays Abduljaleel/university of basrah
crossAxisAlignment: [Link],
mainAxisAlignment:
[Link],
children: <Widget>[
Container(
height: 20.0,
width: 20.0,
color: [Link],
),
Container(
height: 20.0,
width: 20.0,
color: [Link],
),
Container(
height: 20.0,
width: 20.0,
color: [Link],
),
],
),
),
);
}
6- color
import 'package:flutter/[Link]';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: [Link],
body: SafeArea(
child: Row(
Iman Qays Abduljaleel/university of basrah
// crossAxisAlignment: [Link],
mainAxisAlignment: [Link],
children: [
Container(
width: 100,
color: [Link],
),
Container(
width: 100,
height: 100,
color: [Link],
),
Container(
width: 100,
height: 100,
color: [Link],
),
Container(
width: 100,
color: [Link],
),
],
),
),
),
);
}
}
7-
import 'package:flutter/[Link]';
void main() => runApp(MyFlutterApp());
Iman Qays Abduljaleel/university of basrah
class MyFlutterApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: "First App",
home: Scaffold(
appBar: AppBar(
title: Text("Hello Flutter")
),
body: Material(
color: [Link],
child: Center(
child: Text(
"Hello Wrold",
textDirection: [Link],
style: TextStyle(color: [Link], fontSize: 30)
)
)
)
)
);
}
}
8-
import 'package:flutter/[Link]';
void main() => runApp(MyCalculator());
class MyCalculator extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
Iman Qays Abduljaleel/university of basrah
return MaterialApp(
title: '',
home: Calculator(),
);
}
}
class Calculator extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _Calculator();
}
}
class _Calculator extends State<Calculator> {
String text = '0';
double numOne = 0;
double numTwo = 0;
String result = '0';
String finalResult = '0';
String opr = '';
String preOpr = '';
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: null,
backgroundColor: [Link],
body: Container(
margin: [Link](bottom: 20),
child: Column(
mainAxisAlignment: [Link],
children: <Widget>[
Row(
children: <Widget>[
Iman Qays Abduljaleel/university of basrah
Expanded(
child: Text(
text,
style: TextStyle(
color: [Link],
fontSize: 60
),
maxLines: 1,
textAlign: [Link],
),
)
],
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
button("C", Color(0xffa5a5a5), 1),
button("+/-", [Link](165,165,165, 1), 1),
button("%", Color(0xffa5a5a5), 1),
button("/", Color(0xffff9800), 1
)
],
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
button("7", Color(0xff323232), 1),
button("8", Color(0xff323232), 1),
button("9", Color(0xff323232), 1),
button("X", Color(0xffff9800), 1
)
],
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
button("4", Color(0xff323232), 1),
button("5", Color(0xff323232), 1),
button("6", Color(0xff323232), 1),
button("-", Color(0xffff9800), 1
Iman Qays Abduljaleel/university of basrah
)
],
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
button("1", Color(0xff323232), 1),
button("2", Color(0xff323232), 1),
button("3", Color(0xff323232), 1),
button("+", Color(0xffff9800), 1
)
],
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
button("0", Color(0xff323232), 0),
button(".", Color(0xff323232), 1),
button("=", Color(0xffff9800), 1
)
],
)
],
),
),
);
}
Widget button(String btnTxt, Color color, int num) {
Container container;
if(num == 0) {
container = Container(
padding: [Link](bottom: 10),
child: RaisedButton(
onPressed: () {
calculate(btnTxt);
Iman Qays Abduljaleel/university of basrah
},
child: Text(btnTxt,
style: TextStyle(
fontSize: 30
)
),
color: color,
padding: [Link](left:81, top:20, right: 81, bottom: 20),
shape: StadiumBorder(),
)
);
} else {
container = Container(
padding: [Link](bottom: 10),
child: RaisedButton(
onPressed: () {
calculate(btnTxt);
},
child: Text(btnTxt,
style: TextStyle(
fontSize: 30
)
),
color: color,
padding: [Link](20),
shape: CircleBorder(),
)
);
}
return container;
}
void calculate(txtBtn) {
if(txtBtn == 'C') {
text = '0';
numOne = 0;
numTwo = 0;
result = '';
finalResult = '0';
Iman Qays Abduljaleel/university of basrah
opr = '';
preOpr = '';
} else if (opr == '=' && txtBtn == '=' ){
switch(preOpr) {
case '+':
finalResult = add();
break;
case '-':
finalResult = sub();
break;
case 'X':
finalResult = mul();
break;
case '/':
finalResult = div();
break;
}
} else if(txtBtn == '+' || txtBtn == '-' || txtBtn == 'X' || txtBtn == '/' || txtBtn == '=')
{
if (numOne == 0) {
numOne = [Link](result);
} else {
numTwo = [Link](result);
}
switch(opr){
case '+':
finalResult = add();
break;
case '-':
finalResult = sub();
break;
case 'X':
finalResult = mul();
break;
case '/':
finalResult = div();
break;
}
Iman Qays Abduljaleel/university of basrah
preOpr = opr;
opr = txtBtn;
result = '';
} else if (txtBtn == '%') {
result = (numOne / 100).toString();
finalResult = result;
} else if (txtBtn == '.') {
if()
result += '.';
finalResult = result;
} else if (txtBtn == '+/-') {
[Link]('-') ? result = [Link](1): result = '-' + result;
finalResult = result;
} else {
if (result == '0')
result = txtBtn;
else
result = result + txtBtn;
finalResult = result;
}
setState(() {
text = finalResult;
});
}
String add() {
result = (numOne + numTwo).toString();
numOne = [Link](result);
return decimalRemove(result);
}
String sub() {
result = (numOne - numTwo).toString();
numOne = [Link](result);
return decimalRemove(result);
Iman Qays Abduljaleel/university of basrah
}
String mul() {
result = (numOne * numTwo).toString();
numOne = [Link](result);
return decimalRemove(result);
}
String div() {
result = (numOne / numTwo).toString();
numOne = [Link](result);
return decimalRemove(result);
}
String decimalRemove(String _result) {
if (_result.contains('.')) {
List<String> split = _result.split('.');
//[11, 0]
if(!([Link](split[1]) > 0))
return split[0];
}
return _result;
}
Iman Qays Abduljaleel/university of basrah