#rTsd – Road to Surface Duo, das Entwicklertagebuch: Teil 2
Was bisher geschah
- #rTsd – Road to Surface Duo, das Entwicklertagebuch: Teil 1 (Idee, Motivation und Gestaltung)
- (aktuell) #rTsd – Road to Surface Duo, das Entwicklertagebuch: Teil 2 (Erste Schritte in C# und XAML)
Nachdem ich im letzten Beitrag über die Motivation und erste theoretische Schritte berichtete, beschäftigt sich dieser Artikel nun mit den ersten realen Schritten mit C# und XAML, um unsere #rTsd App weiter voran zu bringen.
Wie in der Vergangenheit, so liegt auch in diesem Post der leichte und kostenfreie Einstieg in die Entwicklung von auf Xamarin.Forms basierenden Anwendungen im Fokus. Dies bedeutet, dass manche Schritte, Vorgehensweisen und Implementierungen nicht auf Experten-Niveau ausgeführt werden, sondern in Richtung von Verständlichkeit als auch Simplizität angegangen wurden sowie in der Zukunft auch weiterhin werden.
Danke für das motivierende Feedback
Zuerst möchte ich mich für eure zahlreichen motivierenden Zeilen in Kommentaren als auch dem ersten GitHub Issue und Sternchen bedanken. Es ist heutzutage nicht mehr üblich, dass eine solch offene und aktive Zusammenarbeit der Community ohne Hass und unnötige Besserwisserei zustande kommt. Ein großartiges Gefühl! Danke euch.
Natürlich ist jede/r eingeladen, sich mit Fragen, Anregungen und Ideen bei #rTsd einzubringen. Eine Reise allein ins Unbekannte ist toll, Reiseerfahrungen mit anderen teilen zu können ist besser.
Erstens: Das Arbeitspferd der Entwicklung
Eine Xamarin.Forms Anwendung lässt sich auf vielerlei Art entwickeln. Neben der Entwicklungsumgebung (IDE) Rider von den IntelliJ IDEA Machern JetBrains lässt sich beispielsweise auch der leichtgewichtige Editor Visual Studio Code verwenden. Für die #rTsd App setzen wir auf das langjährige Arbeitspferd von Microsoft: Visual Studio 2019 für Windows. Diese IDE ist als Community-Edition (auch auf dem Mac) kostenlos nutzbar und reicht im Funktionsumfang für ein Hobby-Projekt vollkommen aus. Ein hinterlegter Microsoft Account zur Aktivierung der Entwicklungsumgebung ist im Laufe der Nutzungszeit verpflichtend.
Der Download inklusive der benötigten Komponenten wie den Xamarin Werkzeugen und dem zum Testen optionalen Android Emulator kann je nach darunter liegendem System mehrere zehn Gigabyte betragen.
Auch wenn es hier auch eine Menge an benutzbaren Programmiersprachen wie Visual Basic oder F# gibt, setzen wir hier auf die heutzutage am weitesten verbreitete Sprache C#.
Wie in der Readme.md auf GitHub beschrieben, nutze ich zusätzlich noch die Git Bash for Windows, um mit dem Versionskontrollsystem zu arbeiten. Keine Sorge, für die meisten Aktionen mit GitHub wird das Team-Explorer Feature von Visual Studio verwendet.
Zweitens: Grundlegende Struktur und Architektur
Im genauen Sprech erstellen wir kein Visual Studio Projekt, sondern eine sogenannte Solution (Docs). Eine Solution kann wiederum ein oder mehrere Projekte der verschiedensten Typen enthalten.
Für unsere kleine #rTsd-Applikation besteht unsere Solution vor erst aus:
rTsd, Plattform-agnostisches Xamarin.Forms Projekt, das alle Komponenten enthält, welche unabhängig von dem später ausführenden System abgehandelt werden können. In unserem Fall zielen wir mit der App zwar nur auf Android, nichtsdestotrotz könnten wir noch weitere plattformspezifischere Projekte wie für iOS, UWP und Co. anlegen, um auch diese Betriebssysteme zu unterstützen.
rTsd.Android, plattformspezifisches Projekt für Android, welches das „Eltern-Projekt“ rTsd verwenden kann. Dies ist sozusagen der Wrapper, um eine Android App aus der Xamarin.Forms Applikation zu erstellen. Der Aufbau gleicht dabei der Standard-Struktur, wie man sie auch bei der Android-Entwicklung mit Android Studio finden würde. Es gibt eine MainActivity als auch das, original von Android stammende und etwas verwirrende, Asset Management. Wer also Android in Java oder Kotlin entwickeln kann, fühlt sich hier sofort heimisch, da auch die Methodennamen gleich und nur etwas ver-C#-pisiert sind.
Drittens: Entwurfsmuster aka Pattern
Das rTsd-Projekt verwendet das für das .NET-Ökosystem übliche Model-View-ViewModel (MVVM) Entwurfsmuster (Wiki). Dies bedeutet, wir haben eine grobe Einteilung in vier benötigte Komponenten. Folgende Darstellung soll das Zusammenspiel dieser sehr reduziert aufzeigen.
Service, App-agnostische Schicht, welche sich beispielsweise um die Transformation externer Ressourcen wie in diesem Falle dem RSS-Feed in Instanzen der Modellklassen kümmert. Siehe FeedService.cs. Speziell auf dieses Thema mit all den darunterliegenden spannenden C#-Zuckerchen werde ich in einer der zukünftigen Teile dieser Artikelserie eingehen.
Model, App-verständliche Datenrepräsentation. Hier ist es der RSS-Feed von Dr. Windows. Siehe Feed.cs.
ViewModel, stellt Daten basierend auf den Models und Funktionalität hinter Views bereit. Ein ViewModel sollte im besten Falle nichts von der konkreten Oberflächenimplementierung wissen. Theoretisch könnte man so das gleiche ViewModel für eine Xamarin App oder eine ASP.NET Core Anwendung verwenden. Siehe ItemsViewModel.cs.
View, (Teil-) Views der App, in diesem Beispiel ist es die Listen- oder Detailansicht von Beiträgen. Kümmern sich rein um die grafische Gestaltung der Applikation. Siehe ItemsPage.xaml.cs und ItemsPage.xaml
Viertens: Code in the Shell (Layout)
Vergleichbar mit dem Kult-Anime Ghost in the Shell (Wiki) aus Mitte der 90er beginnt auch die #rTsd App ihr Leben aus einem Template.
Microsoft hat vor wenigen Monaten ein neues Layout-System für Xamarin vorgestellt. Mit dem Shell-Layout (Docs) existiert nun ein Unterbau, der mit den gebräuchlichsten Funktionen für moderne Xamarin.Forms Applikationen vorausgestattet ist.
Dieser neue Unterbau soll dem Entwickler immer wiederkehrende Tipparbeit wie unter anderem zur Navigation innerhalb der App, Tab Bars oder auch die von vielen Android Apps bekannten Drawern ersparen. Im Xamarin Shell Sprech sind dies die Flyouts (Docs).
Somit ist unsere App zum ersten Mal startbar. Wenn alles richtig kompiliert und ausgeführt wird, sieht man das von Microsoft stammende Beispiel, welches mit dem Shell-Layout Template erstellt wird. Dieses lädt zum Stöbern im Quelltext ein, da Microsoft hier mit vielen Inline-Kommentaren auf diverse Features der Shell eingeht.
Fünftens: Schmackhafte UI Library
Ein weiterer Punkt, welchen ich in diesem Projekt gerne einsetzen wollte, war die seit geraumer Zeit immer mal wieder sehr gelobte und quelloffene Xamarin.Forms.PancakeView Library des niederländischen GitHub Benutzers sthewissen. Diese schmackhafte Bibliothek ermöglicht es ohne viel Hickhack, Oberflächenelemente zu erstellen, welche eine einfache Art haben, sonst eher komplexe Eigenschaften wie Rahmenradien, Farbverläufe innerhalb des Elements oder auch Schatten simpel via XAML zu setzen.
Zum nicht zu übersehenden Einsatz kommt die View als Verlaufshintergrund hinter den einzelnen Pages der App. Hierbei wird ein leichter, aber dennoch merkbarer vertikaler Verlauf erzeugt, welcher drei Farben enthält.
Ein weiteres Beispiel für den Einsatz der PancakeView sind die einzelnen Listenelemente in der Ansicht aller Blogbeiträge. Bei diesem so genannten ItemTemplate der CollectionView wird über diese Bibliothek unter anderem der Träneneffekt erzeugt. Damit ist der nicht an allen Ecken gleich eingestellte Rahmenradius gemeint.
Es ist schön zu sehen, dass man, wenn man etwas die Augen offen hält, auch ohne große Angst vor der Wartbarkeit des eigenen Quellcodes auf externe Bibliotheken und somit auf das Expertenwissen anderer Menschen zurückgreifen kann.
Sechstens: Effekthascherei
Nicht alles ist plattformagnostisch lösbar. Ein Beispiel hierfür ist der in der App häufig verwendete Schlagschatteneffekt auf Texten.
Hierfür definiert man im plattformübergreifenden Projekt in der Klasse ShadowEffect.cs eine Art Definition des Effekts. Bei uns sind das zum Beispiel DistanceX, um die Verschiebung des Schattens zum Ursprung auf der x-Achse zu modellieren, als auch DistanceY, um diese auf der y-Ache konfigurierbar zu gestalten.
Die plattform- und elementspezifische Implementierung LabelShadowEffect.cs „linked“ man im Android Projekt mit Klassenannotationen an den Effekt zur oben beschriebenen Definition. Dies müsste man schlussendlich für jede Plattform gezielt implementieren, welche diesen Effekt ebenfalls unterstützen soll.
Anschließend kann man den Effekt zum Beispiel in einer XAML View wie folgt verwenden:
Siebtens: Alles kommt nun zusammen
Das Schöne am Entwickeln ist: Es gibt Momente, wo man all die Fragmente, welche man in harter Gedankenarbeit entworfen hat, zu einem großen Block zusammenführt.
In unserem Fall ist das nun der Service, welcher Daten lädt und damit ViewModels befüllt, welche wiederum die Views zum Leben erwecken. Diese nutzen schlussendlich dann beispielsweise Effekte, um die Views aufzuhübschen.
Wenn man nun die ausgeführte App mit dem in unserem ersten Beitrag erstellten UI-Prototyp vergleicht, so sieht man, dass wir es akzeptabel gut geschafft haben, das ursprünglich angedachte Design auch so in die Tat umzusetzen.
Wie geht es weiter?
Wie im Text erwähnt, haben wir jetzt zwar eine hübsche Oberfläche, aber haben uns nicht mit der realen Datenbeschaffung auseinandergesetzt. Hierfür wird im nächsten Teil der Artikelserie auf den entsprechenden C# Service eingegangen, und wie man diesen mit dem Rest der App verbindet.
Anschließend steht das Thema der Detailansicht auf dem Plan. Hierfür müssen wir uns mit den Themen des html-Renderings und in Text eingebetteten, dynamisch geladenen Bildern auseinandersetzen.
Man sieht, die spannende Reise auf der #roadToSurfaceDuo geht unvermindert weiter!
Ungeduldige oder technisch Interessierte können die Entwicklung auf dem für die App angelegten GitHub Repository verfolgen, mithelfen oder auch einfach nur einmal schauen, wie denn so eine App unter der Haube aussieht.
#communityrocks
Themen:
- Entwicklung
- News
Über den Autor
Tobias Scholze
Bayrischer Open Source- und Community-Enthusiast, Verfechter des neuen Microsoft und Wandler zwischen den Betriebssystemwelten. #communityrocks Von Herzen ein Nerd mit der festen Überzeugung, dass man gemeinsam und durch den Einsatz von moderner IT die Welt für jeden ein Stückchen besser machen kann.