使用した経験を持つ缶誰かCustomSingleChildLayoutとCustomMultiChildLayoutクラスは、それらを使用する方法で(例で)詳細に説明することができます。
私はFlutterを初めて使用し、これらの使用方法を理解しようとしています。ただし、ドキュメントは恐ろしく、明確ではありません。例としてインターネットを調べてみましたが、他のドキュメントはありません。
あなたが助けてくれるなら、私は永遠に感謝します。
ありがとうございました!
使用した経験を持つ缶誰かCustomSingleChildLayoutとCustomMultiChildLayoutクラスは、それらを使用する方法で(例で)詳細に説明することができます。
私はFlutterを初めて使用し、これらの使用方法を理解しようとしています。ただし、ドキュメントは恐ろしく、明確ではありません。例としてインターネットを調べてみましたが、他のドキュメントはありません。
あなたが助けてくれるなら、私は永遠に感謝します。
ありがとうございました!
回答:
まず第一に、私はあなたの苦労を理解できるので、これを手伝って喜んでいると言いたいです-自分でそれを理解することにも利点があります(ドキュメントは素晴らしいです)。
私CustomSingleChildLayoutがCustomMultiChildLayoutあなたに説明した後、何が明白になるでしょう。
CustomMultiChildLayoutこのウィジェットのポイントは、このウィジェットに渡す子を単一の関数でレイアウトできることです。つまり、それらの位置とサイズは互いに依存する可能性があります。これは、たとえば事前に作成されたものを使用して達成できないものですStackます。ウィジェット。
CustomMultiChildLayout(
  children: [
    // Widgets you want to layout in a customized manner
  ],
)さて、さらに2つのステップがあります子供を配置する前に、次のをする必要があります。
children必要があり、LayoutId実際に子として表示したいウィジェットをそのウィジェットに渡しますLayoutId。id独自にそれらをレイアウトするときにそれらにアクセスすること、あなたのウィジェットを識別します。CustomMultiChildLayout(
  children: [
    LayoutId(
      id: 1, // The id can be anything, i.e. any Object, also an enum value.
      child: Text('Widget one'), // This is the widget you actually want to show.
    ),
    LayoutId(
      id: 2, // You will need to refer to that id when laying out your children.
      child: Text('Widget two'),
    ),
  ],
)MultiChildLayoutDelegateレイアウトパーツを処理するサブクラスを作成する必要があります。ここのドキュメントは非常に複雑なようです。class YourLayoutDelegate extends MultiChildLayoutDelegate {
  // You can pass any parameters to this class because you will instantiate your delegate
  // in the build function where you place your CustomMultiChildLayout.
  // I will use an Offset for this simple example.
  YourLayoutDelegate({this.position});
  final Offset position;
}これですべての設定が完了し、実際のレイアウトの実装を開始できます。そのために使用できる方法は3つあります。
hasChildこれにより、特定のID(覚えているLayoutId?)がに渡されたかどうかchildren、つまりそのIDの子が存在するかどうかを確認できます。
layoutChild、すべてのid、すべての子を呼び出す必要があり、正確に一度だけ提供されSize、その子のを提供します。
positionChild、位置Offset(0, 0)を指定したオフセットに変更できます。
概念は今かなり明確になっているように感じます。そのため、この例のデリゲートを実装する方法を説明しますCustomMultiChildLayout。
class YourLayoutDelegate extends MultiChildLayoutDelegate {
  YourLayoutDelegate({this.position});
  final Offset position;
  @override
  void performLayout(Size size) {
    // `size` is the size of the `CustomMultiChildLayout` itself.
    Size leadingSize = Size.zero; // If there is no widget with id `1`, the size will remain at zero.
    // Remember that `1` here can be any **id** - you specify them using LayoutId.
    if (hasChild(1)) {
      leadingSize = layoutChild(
        1, // The id once again.
        BoxConstraints.loose(size), // This just says that the child cannot be bigger than the whole layout.
      );
      // No need to position this child if we want to have it at Offset(0, 0).
    }
    if (hasChild(2)) {
      final secondSize = layoutChild(
        2,
        BoxConstraints(
          // This is exactly the same as above, but this can be anything you specify.
          // BoxConstraints.loose is a shortcut to this.
          maxWidth: size.width,
          maxHeight: size.height,
        ),
      );
      positionChild(
        2,
        Offset(
          leadingSize.width, // This will place child 2 to the right of child 1.
          size.height / 2 - secondSize.height / 2, // Centers the second child vertically.
        ),
      );
    }
  }
}他の2つの例は、ドキュメントからの例(チェックの準備ステップ2)と、パッケージについて少し前に書いた実際の例ですfeature_discovery:MultiChildLayoutDelegate実装とCustomMultiChildLayoutでbuild方法を。
最後のステップは、shouldRelayoutメソッドをオーバーライドすることです。このメソッドはperformLayout、古いデリゲートと比較して(任意でをオーバーライドすることもできますgetSize)、次のようにデリゲートを追加することにより、任意の時点で再度呼び出す必要があるかどうかを簡単に制御しますCustomMultiChildLayout。
class YourLayoutDelegate extends MultiChildLayoutDelegate {
  YourLayoutDelegate({this.position});
  final Offset position;
  @override
  void performLayout(Size size) {
    // ... (layout code from above)
  }
  @override
  bool shouldRelayout(YourLayoutDelegate oldDelegate) {
    return oldDelegate.position != position;
  }
}CustomMultiChildLayout(
  delegate: YourLayoutDelegate(position: Offset.zero),
  children: [
    // ... (your children wrapped in LayoutId's)
  ],
)この例では、1と2をIDとして使用しましたenumが、特定のIDがある場合、IDを処理するには、おそらくを使用するのがおそらく最良の方法です。
あなたは渡すことができますListenableにsuper(例えばsuper(relayout: animation)、あなたが、それは一般的に聴きに基づいてレイアウト処理やトリガーをアニメーション化する場合)。
CustomSingleChildLayoutドキュメンテーションは私が上で説明したことを本当によく説明しており、ここでは、私がそれCustomSingleChildLayoutがどのようにCustomMultiChildLayout機能するかを理解した後に非常に明白になると私が言った理由も見るでしょう:
CustomMultiChildLayoutは、複数のウィジェットのサイズと配置の間に複雑な関係がある場合に適しています。単一の子のレイアウトを制御するには、CustomSingleChildLayoutがより適切です。
これは、使用CustomSingleChildLayoutが上記で説明したのと同じ原則に従うことを意味しますが、子が1つしかないため、IDはありません。代わりに、レイアウトを実装するためのさまざまなメソッドを持つ
を使用する必要がありSingleChildLayoutDelegateます(すべてデフォルトの動作があるため、技術的にはすべてオーバーライドできます)。
getConstraintsForChildこれは、layoutChild上記で渡した制約に相当します。
getPositionForChild、これはpositionChild上記と同等です。
他はすべてまったく同じです(必要LayoutIdではなく、の代わりに子が1つしかないことに注意してくださいchildren)。
MultiChildRenderObjectWidgetこれがCustomMultiChildLayout上に構築されたものです。
これを使用するには、Flutterに関するさらに深い知識が必要であり、やはり少し複雑ですが、レベルがさらに低いため、より多くのカスタマイズが必要な場合は、より良いオプションです。これには、主に1つの利点がありますCustomMultiChildLayout(一般に、より多くの制御が可能です)。
CustomMultiChildLayout サイズができない自分自身をその子に基づいて(参照推論のためのより良いマニュアルに関する問題)。
MultiChildRenderObjectWidgetここでは明確な理由で使用方法を説明しませんが、興味がある場合は、2020年1月20日以降に私が広く使用しているFlutter Clockチャレンジへの私の提出をチェックMultiChildRenderObjectWidgetできます。この記事を、それはすべてがどのように機能するかを少し説明するはずです。
今のMultiChildRenderObjectWidgetところ、CustomMultiChildLayoutそれが可能であり、それを直接使用するLayoutIdと、使用する必要がなく、代わりにRenderObjectの親データに直接アクセスできるなど、いくつかの素晴らしい利点が得られることを覚えておくことができます。
私はすべてのコードをプレーンテキスト(StackOverflowテキストフィールド)で記述したので、エラーが発生した場合は指摘してください。修正します。
LayoutIdグローバルまたはローカルで一意である必要がありますか?つまり、タイプの兄弟ウィジェットでは、子にCustomMultiChildLayout別個LayoutIdのが必要です。
                    LayoutId。つまり、このデータ、idは直接の親によってのみアクセスされます:)
                    CustomMultiChildLayout複数のTextウィジェットをa Columnの内で自動サイズ変更する必要があるシナリオでは非常に便利ですRow。