Úprava zpětné navigace v UWP aplikaci s MvvmCross

Při vývoji mobilních aplikací můžeme často narazit na potřebu manipulace s historií navigace mezi jednotlivými obrazovkami. Protože framework MvvmCross obsahuje mnoho abstrakcí nad cílovým operačním systémem, neobsahuje přímo zabudovaný mechanismus pro úpravu zpětné navigace. Jak můžeme tento požadavek v MvvmCross implementovat?

Motivace

Uvedeme si dva velmi časté scénáře, kdy je velmi vhodné upravit zpětnou navigaci aplikace.

Pokud má aplikace uživatelskou část, která je skryta za přihlašovací obrazovkou, pravděpodobně chcete, aby se uživatel po po přihlášení nevrátil zpětnou navigací znovu na přihlšovací stránku (protože již přihlášen je), ale o jednu úroveň výše. Řešením je vyjmout ze zásobníku zpětné navigace poslední stránku poté, co se uživatel přihlásí.

Login flow
Přihlašovací flow

Druhým případem vybízejícím k manipulaci se zpětnou navigací je talčítko “domů”, které uživateli umožní vrátit se po víceúrovňové navigaci zpět na hlavní hub vaší aplikace. Toho lze docílit buď smazáním všech stránek v historii až na poslední nebo přechodem na hlavní stránku a následným smazáním celého zásobníku zpětné navigace.

Jumping home
Skok “domů”

101 zásobníku zpětné navigace v UWP

Univerzální platforma Windows používá ovladací prvek Frame (rámec) pro práci se navigaci mezi stránkami aplikace. Rámec slouží jako kontejner, který zobrazuje stránky a udržuje stav navigace. Pro nás je nejdůležitější vlastnost BackStack jež je seznam implementující IList a obsahující instance PageStackEntry.

Protože BackStack je IList , můžeme na něm provádět veškeré klasické “listové” operace. Můžeme si tedy vytvořit dvě jednoduché metody – první bude odebírat poslední položku zásobníku zpětné navigace a druhá jej kompletně promaže.

Pro zjištění velikosti zásobníku jsme použili vlastnost BackStackDepth. Ekvivalentně lze použít i vlastnost BackStack.Count .

Pro zvídavé – kromě zásobníku zpětné navigace udržuje Frame také zásobník dopředné navigace, díky čemuž je možné vyvořit v aplikaci navigační flow velmi podobné klasickému chování internetových prohlížečů s šipkami zpět a vpřed.

Integrace do MvvmCross

Logiku pro manipulaci se zpětným zásobníkem je nutné vyvolat ve ViewModelu. Bohužel to není přímo možné, protože manipulace se zásobníkem využívá platformně-specifický kód a ten nelze v Portable Class Library přímo používat.

Přestože bychom mohli vytvořit službu, která toto bude umožňovat, MvvmCross nabízí čistější řešení ve formě presentation hintů.

Presentation hinty jsou třídy, které dědí od MvxPresentationHint a reprezentují úmysl změnit způsob prezentace uživatelského rozhraní.

Již jste se pravděpodobně nepřímo setkali se zabudovaným presentation hintem MvxClosePresentationHint. Ten je vytvořen když zavoláte ve ViewModelu metodu Close. V reakci na tento hint dojde ke zpětné navigaci.

Vytvoření presentation hintů

Hinty by měly být definovány v Core PCL projektu a konvence doporučuje je uložit do složky/namespace PresentationHints.

Oba naše hinty jsou pouze prázdné třídy, protože kromě jejich typu nepotřebujeme žádné doplňující informace. Nic vám však nebrání ve vytvoření komplexnějších hintů se speciálními vlastnostmi.

Vytvoření požadavku na změnu prezentace z ViewModelu

Třída MvxNavigatingObject (od které MvxViewModel dědí) má metodu ChangePresentation která má jeden parametr typu MvxPresentationHint. Lze ji použít velmi snadno:

Zpracování požadavku na změnu prezentace

Presentation hint je vyvolán v PCL, ale musí být zpracován separátně pro každou cílovou platformu přímo v projektu dané aplikace.

MvvmCross implementuje koncept view presenterů. Tyto implementují rozhraní IMvxViewPresenter které vypadá následovně:

Jak si můžete všimnout, view presentery již mají zabudovanou podporu presentation hintů. Každá platforma má ve frameworku implementováný výchozí view presenter, As you can see, the view presenters already have a built-in support for presentation hints. Each platform implements a default view presenter. Pro Windows máme MvxWindowsViewPresenter, který implementuje výchozí chování navigace pomocí Frame. Můžete implementovat vlastní složitější view presentery, pokud to vaše aplikace vyžaduje. V našem případě vystačí už ten výchozí, protože můžeme přímo použít metodu AddPresentationHintHandler pro registraci handlerů našich požadavků.

Nejprve vytvořme třídu, která v konstruktoru očekává IMvxWindowsFrame  (což je obal okolo systémového prvku Frame) a obsahuje handlery jednotlivých hintů:

Kromě manipulace se zpětnou navigací aktualizaujeme viditelnost tlačítka zpět v titulku okna a vracíme true nebo false pokud byl hint zpracován resp. nebyl zpracován. To je užitečné, pokud chceme mít zaregistrovaných více handlerů pro jeden konkrétní presentation hint.

Nakonec handlery přímo zaregistrujeme. Toho lze docílit overridem virtuální metody CreateViewPresenter ve tříde Setup v UWP projektu.

Necháme framework vytvořit výchozí view presenter a přidáme mu dva presentation hint handlery. Tímto způsobem budou zaregistrovány a spuštěny vždy, když ViewModel indikuje požadavek na změnu prezentace.

Zdrojový kód

Ukázkový kód k tomuto příspěvku je dostupný na mém GitHubu. Obsahuje i spustitelnou ukázkovou aplikaci.

Shrnutí

Ukázali jsme si, jak můžeme manipulovat se zpětným zásobníkem v UWP aplikací s MvvmCross. Abychom to dokázali, využili jsme presentation hinty, které byly následně zpracovány view presenterem naší aplikace.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*