Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter Flatter:OrientionBuilder-重用子部件而不重建?_Flutter_Widget_Reusability_Device Orientation - Fatal编程技术网

Flutter Flatter:OrientionBuilder-重用子部件而不重建?

Flutter Flatter:OrientionBuilder-重用子部件而不重建?,flutter,widget,reusability,device-orientation,Flutter,Widget,Reusability,Device Orientation,我正在使用方向生成器定义纵向和横向布局。布局包括两个小部件,例如:TextField小部件和GoogleMap小部件。在“纵向”中,布局使用TabBarView在两个小部件之间水平移动。在“横向”中,小部件并排放置在屏幕上的扩展容器中 如果我更新纵向中的文本字段并更改为横向,数据将丢失。我可以用一个变量来管理它,这很快也很简单。但是,如果我重建地图,它可能已经移动,并添加了数百个标记和线条等,我必须在每次用户更改设备方向时重新绘制每个标记。虽然这是可以实现的,但当存在数百个标记和线条时,重新绘制

我正在使用方向生成器定义纵向和横向布局。布局包括两个小部件,例如:TextField小部件和GoogleMap小部件。在“纵向”中,布局使用TabBarView在两个小部件之间水平移动。在“横向”中,小部件并排放置在屏幕上的扩展容器中

如果我更新纵向中的文本字段并更改为横向,数据将丢失。我可以用一个变量来管理它,这很快也很简单。但是,如果我重建地图,它可能已经移动,并添加了数百个标记和线条等,我必须在每次用户更改设备方向时重新绘制每个标记。虽然这是可以实现的,但当存在数百个标记和线条时,重新绘制需要相当长的时间

问题是,是否有可能在方向更改过程中重用小部件,包括用户添加的任何标记、线条等,而无需每次重新构建?Ie类似于我们用于TabBar切换的AutomaticEpaLiveClientMixin?还是我处理这个问题的方法不对

范例

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,
      ),
    );
  }
}
类测试扩展StatefulWidget{
Test({Key}):super(Key:Key);
@凌驾
TestState createState()=>TestState();
}
类TestState扩展了状态{
TestState({Key});
小部件mMap;
多行文字;
@凌驾
void initState(){
mMap=gMap();
mText=gText();
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回方向生成器(
生成器:(上下文、方向){
返回方向==方向。纵向
?平面布置图()
:景观布局();
},
);
}
控件布局(){
返回脚手架(
正文:DefaultTabController(
长度:2,
子项:选项卡视图(
//物理学:NeverscrollableScroll物理学(),
儿童:[
gText(),
gMap(),
]
),
),
);
}
Widget landscapeLayout(){
返回脚手架(
正文:世界其他地区(
儿童:[
扩大(
子项:gText(),
),
扩大(
儿童:gMap()
),
],
),
);
}
TextField gText(){
返回TextField();
}
谷歌地图gMap(){
返回谷歌地图(
mapType:mapType.hybrid,
initialCameraPosition:CameraPosition(
目标:LatLng(37.0,-122.0),
缩放:2,
),
);
}
}

经过大量努力和测试多个选项后,我得出结论,orientation builder中的两个布局是完全独立的,两个布局永远不会相遇。作为这种特殊情况下的一种解决方法,我放弃了方向生成器,而是创建了一行,其中包含两个宽度均为0的扩展小部件,并根据设备方向更新了flex。例如,在纵向中,1(显示)和0(隐藏)的柔性,如浮动动作条可根据需要反转,在横向中,1和1的柔性可同时显示。也许这不是正确的方法,但它很简单,也许有一天会引起其他人的兴趣

@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()),
            )
          ]
      ),
    );
  }
@覆盖
小部件构建(构建上下文){
if(MediaQuery.of(context.orientation==orientation.scape){
formFlex=1;
mapFlex=1;
}
else if(MediaQuery.of(context.orientation==orientation.taritary&&formFlex==mapFlex){
formFlex=1;
mapFlex=0;
}
返回脚手架(
appBar:getAppBar(),
正文:世界其他地区(
儿童:[
扩大(
flex:formFlex,
子:容器(宽度:0,子:文本('Test1')),
),
扩大(
flex:mapFlex,
子:容器(宽度:0,子:gMap()),
)
]
),
);
}