[英]Flutter: OrientationBuilder - reuse child widgets without rebuilding?
我正在使用 OrientationBuilder 來定義縱向和橫向布局。 布局包括兩個小部件,例如:TextField 小部件和 GoogleMap 小部件。 在“縱向”中,布局利用 TabBarView 在兩個小部件之間水平移動。 在“橫向”中,小部件並排放置在擴展容器中的屏幕上。
如果我以縱向更新 TextField 並更改為橫向,則數據將丟失。 我可以用一個變量來管理它,這既快速又簡單。 但是,如果我重建 Map 可能已經移動並添加了數百個標記和線條等,我必須在每次用戶更改設備方向時重新繪制每個標記。 雖然這是可以實現的,但當存在數百個標記和線條時,重繪需要相當長的時間。
那么問題是,是否可以在方向更改中重用小部件,包括任何用戶添加的標記、線條等,而無需每次都重新構建? 即類似於我們用於 TabBar 班次的 AutomaticKeepAliveClientMixin 的東西? 還是我以錯誤的方式解決這個問題?
例子
class Test extends StatefulWidget {
Test ({Key key}) : super(key: key);
@override
TestState createState() => TestState();
}
class TestState extends State<Test > {
TestState({Key key});
Widget mMap;
Widget mText;
@override
void initState() {
mMap = gMap();
mText = gText();
super.initState();
}
@override
Widget build(BuildContext context) {
return OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? portraitLayout()
: landscapeLayout();
},
);
}
Widget portraitLayout() {
return Scaffold(
body: DefaultTabController(
length: 2,
child: TabBarView(
//physics: NeverScrollableScrollPhysics(),
children: <Widget>[
gText(),
gMap(),
]
),
),
);
}
Widget landscapeLayout() {
return Scaffold(
body: Row(
children: <Widget>[
Expanded(
child: gText(),
),
Expanded(
child: gMap()
),
],
),
);
}
TextField gText() {
return TextField();
}
GoogleMap gMap() {
return GoogleMap(
mapType: MapType.hybrid,
initialCameraPosition: CameraPosition(
target: LatLng(37.0, -122.0),
zoom: 2,
),
);
}
}
經過大量努力和測試多個選項后,我得出結論,方向構建器中的兩種布局是完全獨立的,兩者永遠不會相遇。 作為這種特殊情況下的解決方法,我放棄了方向構建器,而是創建了一個包含兩個寬度均為 0 的擴展小部件的行,並根據設備方向更新了 flex。 例如,在縱向,1(顯示)和 0(隱藏)的 flex 中,浮動操作欄可以根據需要進行反轉,而在橫向 1 和 1 的 flex 中,可以平等地顯示兩者。 可能不是正確的方法,但它很簡單,並且有一天其他人可能會感興趣。
@override
Widget build(BuildContext context) {
if (MediaQuery.of(context).orientation == Orientation.landscape) {
formFlex = 1;
mapFlex = 1;
}
else if (MediaQuery.of(context).orientation == Orientation.portrait && formFlex==mapFlex){
formFlex = 1;
mapFlex = 0;
}
return Scaffold(
appBar: getAppBar(),
body: Row(
children: <Widget>[
Expanded(
flex:formFlex,
child: Container(width: 0, child: Text('Test1')),
),
Expanded(
flex:mapFlex,
child: Container(width: 0, child: gMap()),
)
]
),
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.