Was sind Schlüssel in der Klasse der zustandslosen Widgets?

78

In den Flatterdokumenten finden Sie Beispielcode für eine zustandslose Widget-Unterklasse wie folgt:

class GreenFrog extends StatelessWidget {
  const GreenFrog({ Key key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFF2DBD3A));
  }
}

und das

class Frog extends StatelessWidget {
  const Frog({
    Key key,
    this.color: const Color(0xFF2DBD3A),
    this.child,
  }) : super(key: key);

  final Color color;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return new Container(color: color, child: child);
  }
}

Was ist ein Schlüssel und wann sollte dieser Superkonstruktor verwendet werden? Wenn Sie einen eigenen Konstruktor haben, müssen Sie {Schlüsselschlüssel} haben. Warum? Ich habe andere Beispiele gesehen, in denen das Super-Schlüsselwort nicht verwendet wird, daher ist hier meine Verwirrung.

DanT29
quelle
In gewisser Weise ähnelt das Konzept dem Schlüssel in React stackoverflow.com/questions/28329382/…
onmyway133
1
Diese Jungs könnten Schlüssel verwenden, um die Leistung zu verbessern ... einen Blick wert. Medium.com/flutter-community/…
Stuckedoverflow

Antworten:

108

TLDR: Alle Widgets sollte eine haben Key keyals optionale Parameter oder deren Konstruktor. Keywird von der Flatter-Engine verwendet, um zu erkennen, welches Widget in einer Liste geändert wurde.


Dies ist nützlich, wenn Sie eine Liste ( Column, Rowwas auch immer) von Widgets desselben Typs haben , die möglicherweise entfernt / eingefügt werden können.

Angenommen, Sie haben dies (Code funktioniert nicht, aber Sie haben die Idee):

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("bar")),
    Card(child: Text("42")),
  ]
)

Möglicherweise können Sie jedes dieser Widgets einzeln mit einem Wisch entfernen.

Die Sache ist, unsere Liste hat eine Animation, wenn ein Kind entfernt wird. Entfernen wir also "bar".

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("42")),
  ]
)

Das Problem: Ohne Keykann Flattern nicht wissen, ob das zweite Element von Ihnen Rowverschwunden ist. Oder wenn es der letzte ist, der verschwunden ist und der zweite sein Kind verändert hat.

Ohne Keykönnten Sie möglicherweise einen Fehler haben, bei dem Ihre Urlaubsanimation stattdessen auf dem letzten Element abgespielt wird!


Hier Keyfindet statt.

Wenn wir unser Beispiel erneut mit dem Schlüssel beginnen, haben wir Folgendes:

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("bar"), child: Text("bar")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

Beachten Sie, dass der Schlüssel nicht der untergeordnete Index ist, sondern etwas Einzigartiges für das Element.

Wenn wir ab diesem Punkt "bar" wieder entfernen, haben wir

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

Dank keyder Anwesenheit weiß die Flatter-Engine jetzt genau, welches Widget entfernt wurde. Und jetzt wird unsere Urlaubsanimation korrekt auf "bar" statt auf "42" abgespielt.

Rémi Rousselet
quelle
1
Ich fange an zu verstehen, was Sie sagen. Ich bin auch neu in der mobilen Entwicklung, also nackt mit mir. Nur um aus Ihrer Erklärung zu verdeutlichen, gab es jetzt eine Möglichkeit, die Kartenelemente auseinander zu halten, obwohl sie als Kind einen anderen Text hatten? Um dies zu lösen, wird ein Schlüssel als eindeutige ID für jedes Element verwendet. Ist das richtig?
DanT29
1
Genau. Verwenden Sie zur Unterscheidung von Widgets standardmäßig deren Typ und Index in der Liste, sofern Sie keinen Schlüssel angeben.
Rémi Rousselet
1
Sinnvoller ist, dass ich eine weitere Frage habe, die ich in meinem ursprünglichen Beitrag als Frage 2 aktualisiert habe. Scheint mehr Dartlang, kannst du versuchen, das zu erklären?
DanT29
5
Fügt das Flattern die Standardtaste hinzu?
Ishan Fernando
10
@IshanFernando Nr. Wenn jedoch kein Schlüssel vorhanden ist, verwenden Sie beim Flattern den Widget-Typ und dessen Position im Array als Referenz.
Rémi Rousselet
7

Was sind Schlüssel?

Schlüssel sind IDs für Widgets. Alle Widgets haben sie, nicht nur StatelessWidgets. Sie werden vom Elementbaum verwendet, um zu bestimmen, ob ein Widget wiederverwendet werden kann oder ob es neu erstellt werden muss. Wenn kein Schlüssel angegeben ist (der übliche Fall), wird der Widget-Typ verwendet, um dies zu bestimmen.

Warum Schlüssel verwenden?

Schlüssel sind nützlich, um den Status beizubehalten, wenn sich die Anzahl oder Position von Widgets ändert. Wenn kein Schlüssel vorhanden ist, kann das Flutter-Framework verwirrt sein, welches Widget geändert wurde.

Wann werden Schlüssel verwendet?

Verwenden Sie sie nur, wenn das Framework Ihre Hilfe benötigt, um zu wissen, welches Widget aktualisiert werden soll.

Meistens müssen Sie keine Schlüssel verwenden. Da Schlüssel meist nur zur Aufrechterhaltung des Status nützlich sind, müssen Sie keinen Schlüssel verwenden, wenn Sie ein Widget ohne Status haben, dessen untergeordnete Elemente alle ohne Status sind. Es tut in diesem Fall nicht weh, einen Schlüssel zu verwenden, aber es hilft auch nicht.

Es gibt einige Mikrooptimierungen, die Sie mithilfe von Schlüsseln vornehmen können. Siehe diesen Artikel .

Wo werden Schlüssel verwendet?

Legen Sie den Schlüssel an den Teil des Widget-Baums, an dem die Neuordnung oder das Hinzufügen / Löschen stattfindet. Wenn Sie beispielsweise die Elemente einer ListView neu anordnen, deren untergeordnete Elemente ListTile-Widgets sind, fügen Sie die Schlüssel zu den ListTile-Widgets hinzu.

Welche Art von Schlüsseln soll verwendet werden?

Ein Schlüssel ist nur eine ID, aber die Art der ID kann variieren.

ValueKey

Ein ValueKey ist ein lokaler Schlüssel, der einen einfachen Wert wie eine Zeichenfolge oder eine Ganzzahl annimmt.

ObjectKey

Wenn Ihr Widget komplexere Daten als einen einzelnen Wert anzeigt, können Sie einen ObjectKey für dieses Widget verwenden.

Einzigartiger Schlüssel

Diese Art von Schlüssel gibt Ihnen garantiert jedes Mal eine eindeutige ID. Wenn Sie es jedoch verwenden, fügen Sie es in die buildMethode ein. Andernfalls hat Ihr Widget niemals dieselbe ID und der Elementbaum findet niemals eine Übereinstimmung zur Wiederverwendung.

GlobalKey

GlobalKeys können verwendet werden, um den Status in Ihrer App beizubehalten. Verwenden Sie sie jedoch sparsam, da sie globalen Variablen ähneln. Es ist oft vorzuziehen, stattdessen eine Zustandsverwaltungslösung zu verwenden.

Beispiele für die Verwendung von Schlüsseln

Verweise

Suragch
quelle
4

Der Schlüssel ist ein optionaler Parameter, der zum Beibehalten des Status in Ihrem Widget-Baum erforderlich ist. Sie müssen ihn verwenden, wenn Sie eine Sammlung von Elementen in Ihrem Baum verschieben und den Status beibehalten möchten.

Die beste Erklärung finden Sie in diesem Video von Google. Verwendung von Schlüsseln - Flutter Widgets 101 Ep. 4

d0xzen
quelle
2

Schlüssel ist ein Objekt, mit dem ein Widget eindeutig identifiziert wird.

Sie werden verwendet, um auf den Status In a zuzugreifen oder diesen wiederherzustellen StatefulWidget(meistens benötigen wir sie überhaupt nicht, wenn unser Widget-Baum nur aus zustandslosen Widgets besteht). Es gibt verschiedene Arten von Schlüsseln, die ich anhand der Verwendung erklären möchte.

Zweck ( key types)

1. Mutieren Sie die Sammlung i.e. remove / add / reorder item to listin einem zustandsbehafteten Widget wie einer ziehbaren Aufgabenliste, in der markierte Elemente entfernt werden

➡️ ObjectKey, ValueKey & UniqueKey

2. Verschieben Sie das Widget von einem übergeordneten Element in ein anderes, wobei der Status beibehalten wird.

➡️ GlobalKey

3. Zeigen Sie dasselbe Widget in mehreren Bildschirmen an und halten Sie seinen Status.

➡️ GlobalKey

4. Formular validieren.

➡️ GlobalKey

5. Sie möchten einen Schlüssel ohne Verwendung von Daten vergeben.

➡️ UniqueKey

6. Wenn Sie bestimmte Datenfelder wie die UUID von Benutzern als eindeutigen Schlüssel verwenden können.

➡️ ValueKey

7. Wenn Sie kein eindeutiges Feld als Schlüssel verwenden können, das Objekt selbst jedoch eindeutig ist.

➡️ ObjectKey

8. Wenn Sie mehrere Formulare oder mehrere Widgets desselben Typs haben, die GlobalKey benötigen.

➡️ GlobalObjectKey, LabeledGlobalKey whichever is appropriate, similar logic to ValueKey and ObjectKey

❌ Verwenden Sie nicht zufällig string/numberals Schlüssel, da dies den Zweck von Schlüsseln zunichte macht ❌

Erluxman
quelle