Add statemenegment

pull/3/head
Jonas Franz 3 years ago
parent 0d4b4c0797
commit 747034a340
  1. 3
      chapters/basics/basics.tex
  2. 41
      chapters/basics/flutter.tex
  3. BIN
      chapters/basics/setState_tree.png
  4. 45
      chapters/basics/state-management.tex

@ -2,4 +2,5 @@
In diesem Kapitel werden für die weitere Evaluation benötigte Grundlagen vermittelt. Dabei wird sowohl auf bestehende Literatur eingegangen als auch an Hand von Beispielen Konzepte erläutert.
\input{chapters/basics/flutter.tex}
\input{chapters/basics/flutter.tex}
\input{chapters/basics/state-management.tex}

@ -56,11 +56,37 @@ In Flutter wird bei Widgets grundsätzlich zwischen \texttt{StatelessWidget} und
Ein \texttt{StatelessWidget} hat grundsätzlich keinen veränderbaren Zustand. Dies heißt, dass alle Klassenvariablen unveränderlich sein sollen. In Dart wird dies mit dem Modifikator \texttt{final} gekennzeichnet. Daraus wird impliziert, dass alle Informationen zum Zustand des Widgets aus den im Konstruktor übergebenen werten stammen müssen. Somit wird das Widget nur neu gebaut, wenn sich Änderungen an den Werten des Konstruktors durch Änderungen in der Hierarchie darüber liegenden Widgets ergeben.
Ein \texttt{StatefulWidget} auf der anderen Hand besteht aus zwei Klassen. Zum einen dem \texttt{StatefulWidget} zum anderen dem \texttt{State} dieses Widgets. Diese Widgets vereinen die Möglichkeiten eines \texttt{StatelessWidget} mit der Möglichkeit, den Zustand des Widgets selbstständig zu verändern. Dies wäre beispielsweise bei einem Textfeld relevant, wenn der Text geändert wird. Zustandsänderungen werden dabei über die, wie in \autoref{lst:stateful} gezeigte, \texttt{setState} Methode vorgenommen, damit auch die Änderung an das Framework kommuniziert wird.
Ein \texttt{StatefulWidget} auf der anderen Hand besteht aus zwei Klassen. Zum einen dem \texttt{StatefulWidget} zum anderen dem \texttt{State} dieses Widgets. Diese Widgets vereinen die Möglichkeiten eines \texttt{StatelessWidget} mit der Möglichkeit, den Zustand des Widgets selbstständig zu verändern. Dies wäre beispielsweise bei einem Zähler relevant, wenn der Zähler erhöhrt werden soll. Zustandsänderungen werden dabei über die, wie in \autoref{lst:stateful} gezeigte, \texttt{setState} Methode vorgenommen, damit auch die Änderung an das Framework kommuniziert wird. Intern wird dabei das Widget als \texttt{dirty} markiert, welches dazu führt, dass die Build-Methode des States erneut aufgerufen wird durch das Framework. Entscheidend ist dabei, dass der State persistent bleibt, auch wenn sich beispielsweise Konstruktor-Parameter der \texttt{StatefulWidget}-Klasse ändern.
\begin{lstlisting}[caption={StatefulWidget}, label={lst:stateful}]
UI Widget(state) TODO
class Counter extends StatefulWidget {
const Counter({Key? key}) : super(key: key);
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("Count: $_counter"),
IconButton(icon: Icon(Icons.add),
onPressed: _incrementCounter),
],
);
}
}
\end{lstlisting}
\begin{wrapfigure}{r}{0.33\textwidth}
@ -72,13 +98,6 @@ Ein \texttt{StatefulWidget} auf der anderen Hand besteht aus zwei Klassen. Zum e
Durch die Kombination von diversen Widgets entsteht so ein Widget-Baum, wie in \autoref{fig:flutterTree} zu sehen ist. Dieser Baum lässt sich auch mittels Hilfswerkzeugen traversieren, ist aber von der Grundstruktur für einen unidirektionalen Datenfluss ausgelegt. Dies bedeutete, dass Widgets nur untergeordnete Widgets durch Änderung derer Zustände verändern können sollen. Übergeordnete Widgets können somit - jedenfalls nicht direkt - verändert werden.
Zusammenfassend wird festgehalten, dass der Zustand und die Verwaltung des Zustands von Widgets einen wichtigen Teil im Lebenszyklus einer Flutter-Anwendung ist.
Was ist Flutter?
Wie funktioniert Flutter?
Wie ist die Architektur eine Flutter Anwendung?
Wie funktioniert Testing unter Flutter?
Anders als bei der nativen Entwicklung, wird hier also die Benutzeroberfläche deklarativ programmiert. Bei der Entwicklung wird also festgelegt, wie welches Element bei welchem Zustands auszusehen hat, ohne dabei den Kontrollfluss beschreiben zu müssen.
Zusammenfassend wird festgehalten, dass der Zustand und die Verwaltung des Zustands von Widgets einen wichtigen Teil im Lebenszyklus einer Flutter-Anwendung ist. Dies gibt schon einen Vorgriff darauf, dass hier eine Lösung gefunden werden muss, welche auf diverse Szenarien anwendbar sein muss.

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@ -0,0 +1,45 @@
\pagebreak
\section{Zustandsverwaltung}
Nachdem nun die Grundlagen des Flutter-Frameworks und die Details der Zustandsverwaltung der Widgets im letzten Kapitel erläutert wurden, kann jetzt betrachtet werden, was überhaupt die Zustandsverwaltung umfasst.
\citeauthor{flutterinaction} fasst den Komplex der Zustandsverwaltung in Flutter in seinem Standardwerk \textit{\citetitle{flutterinaction}} wie folgt zusammen:
\begin{displayquote}[{\cite[Kap.8.1.2]{flutterinaction}}]
State management is a combination of passing data around the app, but also re-rendering pieces of your app at the right time. All the re-rendering in Flutter is dependent on the State object and its lifecycle.
\end{displayquote}
Daraus ergibt sich, dass die State-Klasse in der Zustandsverwaltung von Flutter eine wichtige Rolle spielt, und alle Ansätze dieses Konzept benutzen müssen, um in das Flutter-Framework integrierbar zu sein. \citeauthor{flutterinaction} beschreibt dabei die Aufgabe der Zustandsverwaltung eher auf einer Ebene des Datenflusses und des Ablaufs der Neu-Erstellung der Benutzeroberfläche.
\citeauthor{managingstateinflutter} sieht die Zustandsverwaltung dabei eher auf einer eher ablaufszentrierten Sichtweise indem er die Aufgabe der Zustandsverwaltung wie folgt analysiert:
\begin{displayquote}[{\cite[Kap.1]{managingstateinflutter}}]
State management is simply a technique, or multiple techniques, used to take care of the changes that occur in your application.
\end{displayquote}
Als Beispiele nennt er dabei, das Reagieren auf Interaktionen mit der Anwendung oder die Beibehaltung des Datenflusses über mehrere Screens hinweg.
Beide Sichtweisen haben gemein, dass die Grundaufgabe der Zustandsverwaltung die Sicherstellung eines korrekten Zustands der Anwendung, einzelner Screens oder einzelner Widgets sein muss, sowie die mögliche Überführung dieses Zustands in einen neuen Zustand als Reaktion auf Veränderungen.
Nachdem nun eingeführt wurde, was unter einer Zustandsverwaltung in Flutter zu verstehen ist, werden nun mögliche bestehende Ansätze für eine Zustandsverwaltung skizziert, um im weiteren Verlauf der Ausarbeitung im Analyse- und Evaluationskapitel diese eingehender zu untersuchen.
\subsection{Mitgelieferte Werkzeuge}
Die erste Kategorie der Zustandsverwaltungssysteme umfasst jene, welche ohne eine zusätzliche Bibliothek auskommen und somit de facto im Flutter Framework mitgeliefert werden. Hierbei wird mit den einfacheren Konzepten und Werkzeugen begonnen und anschließend die komplexeren Konzepte und Werkzeuge vorgestellt.
\subsubsection{setState}
Die wohl grundlegendeste Möglichkeit, den Zustand in einer Flutter Anwendung zu verwalten stellt das ausschließliche Benutzen der \texttt{setState}-Methode dar. Ein Beispiel zur Verwendung wurde bereits in \autoref{lst:stateful} in der \texttt{incrementCounter}-Methode eingeführt. Hier findet die Speicherung des Zustands also durch die direkte Manipulation des States von StatefulWidgets statt.
\begin{wrapfigure}{l}{0.33\textwidth}
\centering
\includegraphics[width=0.98\linewidth]{chapters/basics/setState_tree.png}
\caption{Flutter Widget Tree bei setState}
\label{fig:flutterTreeSetState}
\end{wrapfigure}
Wie vorausgehend beschrieben, muss ein Zustandsverwaltungssystem aber nicht nur den Zustand einzelner Widgets verwalten können, sondern auch von größeren Ordnungen wie beispielsweise von Screens oder der ganzen Anwendung. Um dies bei diesem Ansatz erreichen zu können, wir der Zustand oder Teile des Zustands über die Konstruktor innerhalb des Widget-Trees weiter nach unten gegeben.
Anschaulich lässt sich dies durch das Beispiel \autoref{fig:flutterTreeSetState} darstellen, welches eine Anwendung, die global speichern muss, welche Person aktuell angemeldet ist, zeigt. Da diese Information in diesem Beispiel an diversen Stellen innerhalb der Anwendung benötigt wird, macht es Sinn, diese Information weit oben im Baum in Form eines \texttt{StatefulWidget} namens \texttt{LoginStateWidget} zu speichern, da der Datenfluss innerhalb des Baums ausschließlich unidirektional von oben nach unten stattfindet. Um diese Information nun an die Widgets zu kommunizieren, die es benötigen - in diesem Fall \texttt{InformationConsumer} - muss \texttt{LoginStateWidget} die Information per Konstruktor an das nachgelagerte Widget weitergeben. Diese nachgelagerten Widgets (\texttt{A, B, C}) müssen dies ebenfalls tun, bis die Information am Ziel \texttt{InformationConsumer} angekommen ist. Diese Anwendungsmuster wird in der Literatur als \blockquote[{\cite[Kap.8.2]{flutterinaction}}]{lifting state up} bezeichnet.
 \subsubsection{InheritedWidget}
Loading…
Cancel
Save