使用した経験を持つ缶誰か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
。