1. ホーム
  2. dart

[解決済み] ステートレスウィジェットクラスのKeyとは何ですか?

2022-09-18 06:13:50

質問

flutterのドキュメントには、ステートレスウィジェットのサブクラスのサンプルコードが掲載されています。

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

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

そして、この

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);
  }
}

キーとは何ですか?このスーパーコンストラクタはいつ使うべきですか?独自のコンストラクタを持つ場合、{Key key}を持たなければならないように思えますが、なぜでしょうか?他の例では、super キーワードが ではなく が使われている他の例を見たので、ここが混乱しているところです。

どのように解決するのですか?

TLDR: すべてのウィジェットに Key key として 任意 パラメータ、またはそのコンストラクタで指定します。 Key は、リスト内のどのウィジェットが変更されたかを認識するステップで flutter engine が使用するものです。


がある場合に便利です。 リスト ( Column , Row など) のウィジェットの が同じタイプの で、潜在的に削除/挿入される可能性があります。

次のようなものがあるとしましょう(コードは動作しませんが、アイデアを得ることができます)。

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

これらのウィジェットをスワイプで個別に削除できる可能性があります。

問題は、子ウィジェットが削除されたときに、リストがアニメーションを表示することです。そこで、"bar" を削除してみましょう。

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

問題点: Key がないと、flutter はその2番目の要素が Row の2番目の要素が消えたかどうかを知ることができません。あるいは、消えたのが最後の1つで、2つ目はその子が変化しているのかどうか。

ということで、なし Key がないと を残す のアニメーションが最後の要素で再生されるというバグが発生する可能性があります!


これは Key が行われます。

もう一度、keyを使った例を始めると、次のようになります。

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

キーが ではなく ではなく、その要素に固有の何かであることに注意してください。

ここから、もう一度"bar"を削除すると、次のようになります。

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

おかげさまで key が存在するおかげで、flutter engine はどのウィジェットが削除されたかを確実に知ることができます。そして今、私たちの を残す アニメーションは "42" ではなく "bar" で正しく再生されるようになりました。