Created
June 18, 2019 01:34
-
-
Save niusounds/9fd5292584542444d8d7c79548a7e34c to your computer and use it in GitHub Desktop.
CustomMultiChildLayoutの使い方
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MyHomePage(title: 'Flutter Demo Home Page'), | |
); | |
} | |
} | |
class MyHomePage extends StatelessWidget { | |
MyHomePage({ | |
Key key, | |
@required this.title, | |
}) : super(key: key); | |
final String title; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(title), | |
), | |
body: CustomMultiChildLayout( | |
delegate: _Delegate(), | |
children: <Widget>[ | |
// 各WidgetをLayoutIdで囲む | |
// idには任意のオブジェクトを指定できる。enumを使ったりすると良さそう。 | |
LayoutId( | |
id: 1, | |
child: Container( | |
child: Text('text 1'), | |
color: Colors.red, | |
), | |
), | |
LayoutId( | |
id: 2, | |
child: Container( | |
child: Text('text 2'), | |
color: Colors.yellow, | |
), | |
), | |
], | |
), | |
); | |
} | |
} | |
class _Delegate extends MultiChildLayoutDelegate { | |
@override | |
void performLayout(Size size) { | |
// この中で全ての子Widgetのidに対してlayoutChildを呼ぶ。 | |
// layoutChildの結果は子Widgetのサイズを返す。 | |
// あるWidgetの大きさに合わせて別のWidgetの大きさや位置を決定するために変数に保持しておくことができる。 | |
final oneSize = layoutChild( | |
1, | |
BoxConstraints.tightFor( | |
width: 100, | |
height: 50, | |
), | |
); | |
// idに該当する子Widgetが必ずしも存在しない場合はhasChildで存在をチェックする。 | |
if (hasChild(2)) { | |
layoutChild( | |
2, | |
BoxConstraints.tight(oneSize * 2), | |
); | |
// 必要に応じて子Widgetのidに対してpositionChildを呼ぶ。 | |
// 呼ばなかった場合はOffset.zero(左上)に配置される。 | |
positionChild(2, oneSize.bottomRight(Offset.zero)); | |
} | |
} | |
@override | |
bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) { | |
// 一度レイアウトしたら二度と変わらないのであればfalse固定で良い。 | |
// なんらかの条件により再レイアウトが必要な場合はtrueを返す。 | |
// oldDelegateには前回build時のインスタンスが渡される。 | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment