Verschachteln von Routen mit flattern
Ich versuche herauszufinden, eine gute architektonische Lösung für Folgendes problem: ich habe folgende Ersten Ebene Routen, die auch bezeichnet werden als layouts:
/onboarding/* -> Shows onboarding layout
/dashboard/* -> Shows dashboard layout
/overlay/* -> shows slide up overlay layout
/modal/* -> shows modal layout
Benutzer weitergeleitet wird, um jede dieser je nach seinen/Ihren auth-Status, Aktionen etc.. ich habe diese Phase richtig.
Probleme entstehen, wenn ich Sie benutzen will Sekundarstufe Routen, die genannt werden kann Seiten, zum Beispiel
/onboarding/signin -> Shows onboarding layout, that displays signin route
/onboarding/plan -> Shows onboarding layout, that displays plan options
/modal/plan-info -> Shows modal layout, over previous page (/onboarding/plan) and displays plan-information page.
Wie kann ich am besten definieren /organisieren diese in einer Weise, wo kann ich effizient route, die den layouts, und die Seiten, die Sie anzeigen? Beachten Sie, dass immer wenn ich route-Seiten in einem layout, das layout ist nicht zu ändern, aber ich möchte Sie animieren, Inhalte (Seiten) ändern sich innerhalb es basiert auf der route.
Bisher konnte ich folgende
import "package:flutter/widgets.dart";
import "package:skimitar/layouts/Onboarding.dart";
import "package:skimitar/layouts/Dashboard.dart";
Route generate(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/onboarding":
page = new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation, Animation<double> secondaryAnimation) {
return new Onboarding();
});
break;
case "/dashboard":
page = new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation, Animation<double> secondaryAnimation) {
return new Dashboard();
});
break;
}
return page;
}
/* Main */
void main() {
runApp(new WidgetsApp(
onGenerateRoute: generate, color: const Color(0xFFFFFFFFF)));
}
Diese Routen auf das boarding und den dashboard-layouts (jetzt nur einfache Behälter, Umhüllung text). Ich glaube auch, dass ich verwenden können PageRouteBuilder
letztere zu animieren, übergänge zwischen den Routen? Jetzt muss ich herausfinden, wie so etwas wie verschachtelte Sekundär-router innen auf das boarding und dashboard.
Unten ist so etwas wie eine visuelle Darstellung von dem, was ich erreichen möchte, ich muss in der Lage sein, um erfolgreich zu route blau und rot bits. In diesem Beispiel solange wir unter /dashboard
blue bit (layout) ändern sich nicht, aber als wir die Navigation von sagen /dashboard/home
zu /dashboard/stats
den roten bit (Seite) sollte fade-out und fade-in " mit neuen Inhalten. Wenn wir navigieren Weg von /dashboard/home
zu sagen /onboarding/home
, die rote bit (layout) sollte verschwinden, zusammen mit der gerade aktiven Seite und zeigen neue layout für das onboarding und die Geschichte geht weiter.
BEARBEITEN ich ein wenig den Fortschritt mit der Annäherung unten beschrieben, im wesentlichen werde ich bestimmen, das layout in meinem runApp
und erklären neue WidgetsApp
und Routen, die innerhalb jedes der layouts. Es scheint zu funktionieren, aber es gibt ein Problem, Wenn ich auf "Anmelden" ich bin Weiterleitung zur richtigen Seite, aber ich kann auch sehen, alte Seite unten.
main.dart
import "package:flutter/widgets.dart";
import "package:myProject/containers/layouts/Onboarding.dart";
/* Main */
void main() {
runApp(new Onboarding());
}
Onboarding.dart
import "package:flutter/widgets.dart";
import "package:myProject/containers/pages/SignIn.dart";
import "package:myProject/containers/pages/SignUp.dart";
import "package:myProject/services/helpers.dart";
/* Onboarding router */
Route onboardingRouter(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/":
page = buildOnboardingRoute(new SignIn());
break;
case "/sign-up":
page = buildOnboardingRoute(new SignUp());
break;
default:
page = buildOnboardingRoute(new SignIn());
}
return page;
}
class Onboarding extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF000000),
image: new DecorationImage(
image: new AssetImage("assets/images/background-fire.jpg"),
fit: BoxFit.cover)),
child: new WidgetsApp(
onGenerateRoute: onboardingRouter, color: const Color(0xFF000000)),
);
}
}
Anmeldung.dart
import "package:flutter/widgets.dart";
class SignUp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text("Sign Up",
style: new TextStyle(color: const Color(0xFFFFFFFF))));
}
}
Helfer.dart
import "package:flutter/widgets.dart";
Route buildOnboardingRoute(Widget page) {
return new PageRouteBuilder(
opaque: true,
pageBuilder: (BuildContext context, _, __) {
return page;
});
}
- Was versuchen Sie zu erreichen, genau durch die Verschachtelung Router ? Wie würden Sie es verwenden ? Es gibt mehrere Wege, um zu erhalten das gleiche layout, ohne verschachtelte router. So ist es schwer, eine Antwort zu geben, dass werden erfüllen Ihre Bedürfnisse
- Meine app hat mehrere layouts, die jeweils diese layouts können anzeigen von Inhalten basierend auf der Strecke. Ich brauche nicht diese Inhalte werden, fullscreen, nur besetzen bestimmter Raum in einem layout. Ich dachte, es wäre auch schön, um zu entscheiden, welches layout angezeigt wird, über die Routen in der oberen Ebene.
- Es kann sein ungewöhnliches Ding an zu flattern, nehme ich von diesem Konzept reagieren-native, es ist super einfach zu tun, aber ich habe Schwierigkeiten, es herauszufinden hier. Wie, Sie davon ausgehen, öffnen Sie ein modales über die route, und diese modalen Verknüpfungen innerhalb der es weitere verschachtelte routing erfolgt innerhalb von es.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Während es technisch möglich ist nest "Navigator", das ist unrecommended hier (wie es bricht Held animation)
Können Sie
onGenerateRoute
zu bauen verschachtelte 'Routen', die im Fall einer route '/dashboard/Profil", erstellen Sie einen BaumWidgetApp > Dashboard > Profile
. Was ich davon ausgehen ist, was Sie zu erreichen versuchen.Kombiniert mit einer höheren Ordnung-Funktion, können Sie etwas haben, das schafft
onGenerateRoute
für Sie.Um eine Ahnung von der code-flow: die
NestedRoute
vernachlässigt die genauen erstellen des Layouts, lassen es in derbuilder
Methode (z.B.builder: (child) => new Dashboard(child: child),
). Beim aufrufen derbuildRoute
- Methode generieren wir einenPageRouteBuilder
für die sehr Instanz von dieser Seite, aber lassen_build
verwalten, die Schaffung derWidgets
. In_build
wir werden entweder diebuilder
wie es ist - oder lass es Blasen die subroute, wird durch Aufruf der angeforderten subroute, ruft seinen eigenen_build
. Sobald Sie dies getan haben, werden wir mit der integrierten subroute als argument für unseren generator. Lange Geschichte kurz, Sie rekursiv Tauchen Sie ein in weiter Weg Ebenen zu bauen, ist die Letzte Stufe der route, dann lassen Sie es Aufstieg aus der Rekursion und verwenden Sie das Ergebnis als argument für die äußere Ebene und so weiter.BuildNestedRoutes
tut die schmutzige Arbeit für Sie und analysiert die Listen derNestedRoutes
Aufbau der notwendigenRouteSettings
.So, aus dem folgenden Beispiel
Beispiel :
Hier können Sie ganz einfach definiert, Ihre verschachtelten Routen (name + zugehörige Komponente).
Und
NestedRoute
Klasse +buildNestedRoutes
Methode sind auf diese Weise definiert :Diese Weise Ihre
Foo
undBar
Komponenten nicht eng gekoppelt werden mit Ihren routing-system ; aber noch verschachtelte Routen.Es ist mehr lesbar, dann haben Sie Ihre Routen abgesetzt, alle über dem Platz. Und Sie werden leicht einen neuen hinzufügen.
routes
Eigenschaft vonWidgetApp
führen wird, zu viel Wiederholung. Es wird funktionieren, aber wird weniger wartbar dann dieser Ansatz. Besonders auf größeren Strecken./dashboard/profile/{userId}
mit wenig bis keine änderung. Sie können auch stecken Sie einen code-generator zu extrahieren, die Konstruktor Parameter mit der Analyse und Typ-überprüfung.Anyhow is this code still re-drawing also Dashboard whenever I want to navigate from profile (dashboard/profile) to foo (dashboard/foo)?
Das ist eine interessante Frage. Das Beispiel, das ich gegeben wird. Aber Sie könnten memoize-widgets erstellen + verwenden repaintBoundaries um dies zu verhindern. (das ist ein weiterer Vorteil dieses Vorgehens)Können Sie das standard - Navigator als verschachtelte, ohne zusätzliche tricks.
Alle was Sie brauchen, es ist zum zuweisen eines global key und geben Sie die erforderlichen Parameter. Und natürlich, Sie brauchen, um über die android-zurück-Taste Verhalten.
Die einzige Sache, die Sie wissen müssen, ist, dass der Kontext dieser navigator wird nicht global sein. Es werden einige spezifische Punkte in der Arbeit mit ihm.
Folgende Beispiel ist ein bisschen mehr kompliziert, aber es erlaubt Ihnen, zu sehen, wie können Sie die verschachtelten Routen von innen und außen für das navigator-widget. Im Beispiel nennen wir
setState
im root-Seite für die neue route voninitRoute
vonNestedNavigator
.Finden Sie einige zusätzliche Informationen in der nächsten Artikel.
Die Muster, die Sie versuchen zu bauen, auch wenn ihm dies zumutbar ist, scheint es nicht dargestellt werden kann out of the box mit Flattern.BEARBEITEN: das Verhalten, Das Sie erreichen wollen, erfordert die Verwendung von onGenerateRoute, jedoch noch nicht (Jan'18) ordnungsgemäß dokumentiert (doc). Siehe @Darky Antwort um ein Beispiel. Er schlägt vor
NestedRouteBuilder
undNestedRoute
Implementierungen, die Lücke.Mit klarem Navigator von einer MaterialApp, Routen und Seiten-navigation (nach doc) haben sich zwei wesentliche Merkmale, die leugnen, was Sie erreichen wollen (zumindest direkt). Auf der einen Seite, die
Navigator
verhält sich wie ein stack, so schieben und knallen Routen, eine auf der Oberseite des nächsten und so weiter, auf der anderen Routen sind entweder Vollbild oder modal - das heißt, Sie besetzen den Bildschirm teilweise, aber Sie hemmen die Interaktion mit den widgets unter. Mehr explizite, Ihr Paradigma zu verlangen scheint die gleichzeitige Interaktion mit Seiten, die auf verschiedenen Ebenen im Stapel, die nicht auf diese Weise getan.Außerdem fühlt es sich wie der Weg Paradigma ist nicht nur eine Hierarchie - Allgemeine frame → spezifische Unterseite - aber in Erster Instanz eine Darstellung der stack im navigator. Ich selbst habe betrogen, aber es wird deutlich Lesen diese:
Einen möglichen workaround, wie daraus folgt, ist, zu nutzen, die Pfadnamen zu instanziieren des Kind-widgets, um einen state-variable, um zu wissen, was um zu zeigen:
Jedoch ist dies keine stack-Speicher auf dem niedrigeren Niveau. In Fall, dass Sie behandeln möchten, die Reihenfolge der subroutes-widget - Sie können wickeln Sie die subroute container in einem
WillPopScope
, zu definieren, was es tun soll, wenn der Benutzer drücktback
- Taste, und speichern Sie die Reihenfolge der subroutes in einem Stapel. Aber ich fühle mich nicht wie suggeriert so eine Sache.Mein letzten Vorschlag ist die Implementierung von einfachen Strecken - ohne "Stufen" -, verwalten von benutzerdefinierten übergänge zum ausblenden der Veränderung der "äußeren" layout und übergeben Sie die Daten durch die Seiten, oder halten Sie in eine richtige Klasse bietet Ihnen app-Zustand.
PS: check auch Held Animationen, Sie können Ihnen die Kontinuität, die Sie suchen zwischen den Ansichten.