CustomSingleChildLayout
および CustomMultiChildLayout
クラスの使用経験がある人は、それらの使用方法を(例を挙げて)詳細に説明できますか?.
私はFlutterを初めて使用し、これらの使用方法を理解しようとしています。ただし、ドキュメントは恐ろしく、明確ではありません。例としてインターネットを調べようとしましたが、他のドキュメントはありません。
あなたが助けてくれるなら、私は永遠に感謝します。
ありがとうございました!
まず第一に、私はあなたの苦労を理解できるので、これであなたを助けてうれしいと言いたいです-自分でそれを理解することにも利点があります(ドキュメントは素晴らしいです)。
CustomSingleChildLayout
の説明は、CustomMultiChildLayout
を説明した後で明らかになります。
CustomMultiChildLayout
このウィジェットのポイントは、このウィジェットに渡す子を1つの関数でlayoutできるようにすることです。つまり、位置とサイズは相互に依存する可能性があります、これはあなたがを使って達成できないものです。例:ビルド済みの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、すべての子、提供された正確に1回、その子の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つの例は、ドキュメントからの例です(準備を確認step 2)と実世界例 _feature_discovery
_ パッケージ: MultiChildLayoutDelegate
implementation および CustomMultiChildLayout
in build
メソッド 。
最後のステップは shouldRelayout
method をオーバーライドすることです。これは、古いデリゲートと比較して、任意の時点で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)
],
)
_
この例では、idsとして_1
_および_2
_を使用しましたが、enum
を使用することはおそらく特定のIDがある場合にIDを処理する最良の方法。
Listenable
をsuper
に渡すことができます(例:super(relayout: animation)
)。これは、レイアウトプロセスをアニメーション化したり、一般にリスナブルに基づいてトリガーしたりする場合に使用します。
CustomSingleChildLayout
ドキュメント は、私が上で説明したことを非常によく説明し、ここで、CustomSingleChildLayout
がCustomMultiChildLayout
の仕組みを理解した後で非常に明白になると言った理由もわかります。
CustomMultiChildLayout は、複数のウィジェットのサイズと配置の間に複雑な関係がある場合に適しています。単一の子のレイアウトを制御するには、 CustomSingleChildLayout がより適切です。
これはまた、CustomSingleChildLayout
を使用すると、上記で説明したのと同じ原則に従いますが、子が1つしかないため、IDはありません。
代わりに SingleChildLayoutDelegate
を使用する必要があります。これには、レイアウトを実装するためのさまざまなメソッドがあります(これらにはすべてデフォルトの動作があるため、技術的にすべてオーバーライド):
getConstraintsForChild
、これは上記のlayoutChild
に渡した制約と同等です。
getPositionForChild
、これは上記のpositionChild
と同等です。
それ以外はまったく同じです(LayoutId
は必要なく、children
ではなく子が1つしかないことに注意してください)。
MultiChildRenderObjectWidget
これがCustomMultiChildLayout
の土台です。
これを使用するには、Flutterに関するさらに深い知識が必要であり、やはり少し複雑ですが、レベルがさらに低いため、より多くのカスタマイズが必要な場合は、このオプションが適しています。これには、CustomMultiChildLayout
よりもmajorの利点が1つあります(通常、より多くの制御があります)。
CustomMultiChildLayout
サイズを指定できません自身に基づいてその子( 推論のためのより良いドキュメントに関する問題 を参照)。
ここではMultiChildRenderObjectWidget
の使用方法を明確な理由で説明しませんが、興味がある場合は、チェックアウトできます フラッタークロックチャレンジへの私の提出 2020年1月20日以降私はMultiChildRenderObjectWidget
を広範に使用しています。 これに関する記事 を読むこともできます。これにより、すべてがどのように機能するかが少し説明されます。
今のところ、MultiChildRenderObjectWidget
がCustomMultiChildLayout
を可能にするものであり、それを直接使用すると、LayoutId
を使用する必要がなく、代わりにRenderObject
の親データを直接。
私はすべてのコードをプレーンテキスト(StackOverflowテキストフィールド)で記述したので、エラーが発生した場合は指摘してください。修正します。