Skip to content

Commit

Permalink
FINAL
Browse files Browse the repository at this point in the history
petrnymsa committed May 27, 2020
1 parent 89134ad commit f9ea0dc
Showing 9 changed files with 118 additions and 123 deletions.
2 changes: 1 addition & 1 deletion FITthesis.cls
Original file line number Diff line number Diff line change
@@ -236,7 +236,7 @@ a~z\'arove\v n sa zav\"azuje spr\'\i stupni\v t zdrojov\'y k\'od tak\'eho diela
}\else{%
I hereby declare that the presented thesis is my own work and that I have cited all sources of information in accordance with the Guideline for adhering to ethical principles when elaborating an academic final thesis.

I acknowledge that my thesis is subject to the rights and obligations stipulated by the Act No.\,121/2000~Coll., the Copyright Act, as amended. In accordance with Article~46~(6) of the Act, I hereby grant a nonexclusive authorization (license) to utilize this thesis, including any and all computer programs incorporated therein or attached thereto and all corresponding documentation (hereinafter collectively referred to as the ``Work''), to any and all persons that wish to utilize the Work. Such persons are entitled to use the Work in any way (including for-profit purposes) that does not detract from its value. This authorization is not limited in terms of time, location and quantity. However, all persons that makes use of the above license shall be obliged to grant a license at least in the same scope as defined above with respect to each and every work that is created (wholly or in part) based on the Work, by modifying the Work, by combining the Work with another work, by including the Work in a collection of works or by adapting the Work (including translation), and at the same time make available the source code of such work at least in a way and scope that are comparable to the way and scope in which the source code of the Work is made available.
I acknowledge that my thesis is subject to the rights and obligations stipulated by the Act No.\,121/2000~Coll., the Copyright Act, as amended. In accordance with Article~46~(6) of the Act, I hereby grant a nonexclusive authorization (license) to utilize this thesis, including any and all computer programs incorporated therein or attached thereto and all corresponding documentation (hereinafter collectively referred to as the ``Work''), to any and all persons that wish to utilize the Work. Such persons are entitled to use the Work in any way (including for-profit purposes) that does not detract from its value. This authorization is not limited in terms of time, location and quantity. However, all persons that makes use of the above license shall be obliged to grant a~license at least in the same scope as defined above with respect to each and every work that is created (wholly or in part) based on the Work, by modifying the Work, by combining the Work with another work, by including the Work in a collection of works or by adapting the Work (including translation), and at the same time make available the source code of such work at least in a~way and scope that are comparable to the way and scope in which the source code of the Work is made available.
}\fi\fi
}\@declarationOptionSelectedtrue\fi
\ifx5#1 \DeclareRobustCommand{\thedeclarationofauthenticity}{\if\@lang1{%
8 changes: 4 additions & 4 deletions chapters/00_introduction.tex
Original file line number Diff line number Diff line change
@@ -5,14 +5,14 @@

\begin{figure}[htp]
\centering
\includegraphics[width=0.9\linewidth]{img/introduction/so-flutter-trend.pdf}
\includegraphics[width=0.88\linewidth]{img/introduction/so-flutter-trend.pdf}
\caption{Flutter Trend Against Other Popular Frameworks~\cite{so-flutter-trend}.}
\label{fig:so-flutter-trend}
\end{figure}

During~2017, the~concept of another approach was proposed, where the~application uses low-level platform API to draw over the whole screen with keeping high performance and access to native features. Later on, from this concept open-source framework Flutter, made by Google, was created~\cite{flutter}.

The Flutter for the last three years until now (first half of 2020) started to gain developers attention, and it was highly promoted by Google. One indication of its growing popularity is \textit{Stack~Overflow Developer Survey~2019}~\cite{so-2019-survey} where it took third place of ``Most Loved'' framework directly after \textit{.NET Core} and \textit{Torch/PyTorch} and highly growing trend among questions created during the last years (\Cref{fig:so-flutter-trend}). However, like with every new technology, the Flutter can become well-known and well used or will be left as a dead-end.
Flutter for the last three years until now (first half of 2020) started to gain developers attention, and it was highly promoted by Google. One indication of its growing popularity is \textit{Stack~Overflow Developer Survey~2019}~\cite{so-2019-survey} where it took third place of ``Most Loved'' framework directly after \textit{.NET Core} and \textit{Torch/PyTorch} and highly growing trend among questions created during the last years (\Cref{fig:so-flutter-trend}). However, like with every new technology, the Flutter can become well-known and well used or will be left as a dead-end.

\section{Motivation}
There are many reasons why the author chose this topic for the thesis. First of all, his bachelor thesis~\cite{nymsap-bp} already focused on mobile application development, although it used different cross-platform technology -- Xamarin. During his ongoing studies, the author discovered and started to use new, by his opinion, promising framework Flutter. So his first goal and motivation was to study Flutter more in-depth and bring comprehensive study material of this framework for others. The second reason was to conclude if Flutter can become a framework which can be used to create production-ready applications or if it is still an experimental framework. Last reason was motivation to create complex, and yet, simple to use mobile application for everyone who seeks to find new cafes to visit.
@@ -21,8 +21,8 @@ \section{Structure}
The thesis is divided to four chapters:
\begin{itemize}
\item \Cref{ch:flutter} deals with introduction to Flutter framework, its concept~and internal functionality.
\item \Cref{ch:analysis} introduce proposed Coffee Time application. Describes the~created prototype and its user testing. The~analysis of back-end services is described.
\item \Cref{ch:implementation} describes process of back-end implementation as well of Coffee Time application. In the chapter, details how its implemented, which approaches was taken and how development process was done.
\item \Cref{ch:analysis} introduces proposed Coffee Time application. It describes the~created prototype and its user testing. The~analysis of back-end services is also described.
\item \Cref{ch:implementation} describes a~process of back-end implementation as well as of Coffee Time application implementation. In the~chapter, details how its implemented, which approaches was taken and how development process was done.
\item \Cref{ch:testing} describes final application release and its testing.
\end{itemize}
In conclusion, the results are compared with the goals of this thesis.
15 changes: 7 additions & 8 deletions chapters/01_flutter.tex
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ \subsection{Reactive Programming}
\subsubsection{The Notion of Streams}
A Stream can be described as ``A pipe with two ends, only one allowing to insert something into it. When something is inserted into the pipe, it flows inside the pipe and goes out by the other end''~\cite{reactive-didier}. The~Stream can convey any~data type, from simple values to~events, complex object or even another stream. The~data can come to the~Stream, for example, from an external data source such as server connection or from events such as user interactions. In~Dart, the Streams support manipulating them, filtering, re-grouping, modify data before they are send and~much more. This functionality can be used to build reactive \gls{ui}. Flutter has several widgets supporting streams to rebuild part of the~\gls{ui} whenever new data arrived into the~Stream.

The answer to the question ``What is reactive programming$?$'' could be ``Reactive programming is programming with asynchronous data streams``~\cite{reactive-didier}\cite{reactive-red-hat}. Within Flutter framework, anything from an~interaction event (a~tap, a~gesture), changes of a~variable, messages, everything that may change is conveyed and triggered by streams.
The answer to the question ``What is reactive programming$?$'' could be ``Reactive programming is programming with asynchronous data streams`` \cite{reactive-didier}\cite{reactive-red-hat}. Within Flutter framework, anything from an~interaction event (a~tap, a~gesture), changes of a~variable, messages, everything that may change is conveyed and triggered by streams.
It means that with reactive programming, according to~\cite{reactive-didier}, the~application:
@@ -263,14 +263,14 @@ \subsection{Case Study Note}
Following lines in this section introduce some used patterns and solutions for state management. Every solution will use the same case study but with appropriate implementation. Each solution's full code is available as an~appendix. The design and functionality remain the same as introduced before.
% --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- #
\subsection{Inherited Widget}
One solution offered by \textit{Flutter} framework is the concept of \textit{InheritedWidget}~\cite{flutter-inherited-widget}~\cite{notion-widget-didier}. This concept is used across the framework -- for example, obtaining current \textit{Theme} or screen device information through \textit{MediaQuery} object. Both can be accessed through convention ``of'' method -- \verb|Theme.of(context)| returns \textit{Theme} object. Internally these objects makes usage of InheritedWidget. InheritedWidget has two features:
One solution offered by \textit{Flutter} framework is the concept of \textit{InheritedWidget}~\cite{flutter-inherited-widget}~\cite{notion-widget-didier}. This concept is used across the framework -- for example, obtaining current \textit{Theme} or screen device information through \textit{MediaQuery} object. Both can be accessed through convention ``of'' method -- \verb|Theme.of(context)| returns \textit{Theme} object. Internally these objects makes usage of an~\textit{InheritedWidget}. The~\textit{InheritedWidget} has two features:
\begin{itemize}
\item It can be accessed from any widget directly.
\item Whenever the widget changes, the accessing widget is automatically rebuilt.
\end{itemize}
The second implies that, for example, whenever widget access the~\textit{MediaQuery} and it is changed (the device is rotated, resolution changed,\ldots ), the~widget is rebuilt to handle these changes.
The~second implies that, for example, whenever widget access the~\textit{MediaQuery} and it is changed (the device is rotated, resolution changed,\ldots ), the~widget is rebuilt to handle these changes.
\begin{listing}[ht]
\begin{minted}{dart}
@@ -645,9 +645,7 @@ \subsection{Notion of Keys}
\label{listing:keys_page_stateless}
\end{listing}
The~problem can occur when some widget uses a~collection of widgets of the~same type that holds some state. Consider a~concrete example where \verb|SquarePage| holds a~list of \verb|Square| widgets~(\Cref{listing:keys_page_stateless}). Each \verb|Square| (as a~\textit{StatelessWidget}) has defined random colour through a~constructor. After a~button is clicked, the~squares are swapped. With \verb|Square| as \textit{StatelessWidgets}, everything works as expected.
\begin{listing}[ht]
\begin{listing}[!htb]
\begin{minted}{dart}
class Square extends StatefulWidget {
Square({Key key}) : super(key: key);
@@ -672,8 +670,9 @@ \subsection{Notion of Keys}
\label{listing:keys_square_stateful}
\end{listing}
However, if the~\verb|Square| becomes \textit{StatefulWidget}~(\Cref{listing:keys_square_stateful}) and the~button is clicked, it seems like nothing happened -- squares stay on the same place. When the~widget is marked to rebuilt, it walks through \textit{Elements} and if the~widget type and the~\textit{Key} match, the~\textit{Element} updates its reference to new Widget. In the~case of \textit{StatefulWidget}, the~associated state is linked to the~\textit{Element} object~(\Cref{fig:keys_start}). When squares are shifted, the~\textit{Element} is marked as dirty. It walks through square's \textit{StatefulElement} and checks if the~widget type and the~\textit{Key} match. They match because no \textit{Keys} are assigned to them. Hence, the~\textit{Element} updates its widget reference, but the~associated state remains the~same~(\Cref{fig:keys_wrong}).
The~key is to add \textit{Key}. There are several types of Keys such as \textit{ValueKey}, where some unique value can be assigned (for example article's id). For \verb|Square| example, the~\textit{UniqueKey} which generates unique identification is enough for usage. After the~\textit{Keys} are assigned, \mint{dart}|final squares = [Square(key: UniqueKey()),Square(key: UniqueKey())]| the example works again as expected. The~full example code is available as~before within appendix.
The~problem can occur when some widget uses a~collection of widgets of the~same type that holds some state. Consider a~concrete example where \verb|SquarePage| holds a~list of \verb|Square| widgets~(\Cref{listing:keys_page_stateless}). Each \verb|Square| (as a~\textit{StatelessWidget}) has defined random colour through a~constructor. After a~button is clicked, the~squares are swapped. With \verb|Square| as \textit{StatelessWidgets}, everything works as expected.
However, if the~\verb|Square| becomes \textit{StatefulWidget}~(\Cref{listing:keys_square_stateful}) and the~button is clicked, it seems like nothing happened --~squares stay on the same place. When the~widget is marked to rebuilt, it walks through \textit{Elements} and if the~widget type and the~\textit{Key} match, the~\textit{Element} updates its reference to new Widget. In the~case of \textit{StatefulWidget}, the~associated state is linked to the~\textit{Element} object~(\Cref{fig:keys_start}). When squares are shifted, the~\textit{Element} is marked as dirty. It walks through square's \textit{StatefulElement} and checks if the~widget type and the~\textit{Key} match. They match because no \textit{Keys} are assigned to them. Hence, the~\textit{Element} updates its widget reference, but the~associated state remains the~same~(\Cref{fig:keys_wrong}).
The~key is to add \textit{Key}. There are several types of Keys such as \textit{ValueKey}, where some unique value can be assigned (for example article's id). For \verb|Square| example, the~\textit{UniqueKey} which generates unique identification is enough for usage. After the~\textit{Keys} are assigned, \mint{dart}|final squares = [Square(key: UniqueKey()),Square(key: UniqueKey())]| the example works again as expected. The~full example code is available as~before within appendix.
The keys should be put to the most top widget, which is used as a~root widget of collection. Otherwise, the rebuilding algorithm fails once again, and wrong behaviour will occur. In practice, \textit{Key} should be used when stateful widgets are used within collections (such as \textit{ListView}, \textit{Row} or \textit{Column}) and they are manipulated -- moved, removed and similar. Moreover, sometimes the \textit{GlobalKey} can be used to manage some widget's state ``outside''. This approach is often used with managing text inputs.
% --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- # --- #
Loading

0 comments on commit f9ea0dc

Please sign in to comment.