Dart 有没有办法设置管线的渲染顺序?

Dart 有没有办法设置管线的渲染顺序?,dart,flutter,flutter-layout,Dart,Flutter,Flutter Layout,基本上,我想呈现一个依赖于它下面路径中的某个小部件的 为了实现这一点,我正在使用一个GlobalKey,我将它连接到下面路径中的一个小部件上: ///在较低路径中(在较低路径中的小部件) @凌驾 小部件构建(构建上下文){ 返回容器( 关键:环球银行, 孩子:。。, ); } ///上游路线(不同等级!) ///使用lower route窗口小部件中的点击函数调用 ///‘showModalRoute(globalKey)’ @凌驾 小部件构建页面(构建上下文、动画、动画辅助动画){ final

基本上,我想呈现一个依赖于它下面路径中的某个小部件的

为了实现这一点,我正在使用一个
GlobalKey
,我将它连接到下面路径中的一个小部件上:

///在较低路径中(在较低路径中的小部件)
@凌驾
小部件构建(构建上下文){
返回容器(
关键:环球银行,
孩子:。。,
);
}
///上游路线(不同等级!)
///使用lower route窗口小部件中的点击函数调用
///‘showModalRoute(globalKey)’
@凌驾
小部件构建页面(构建上下文、动画、动画辅助动画){
final renderBox=globalKey.currentContext.finderObject()作为renderBox;
最终尺寸=renderBox.Size;
返回大小框(
宽度:size.width,
高度:size.height,
孩子:。。,
);
}
我正试图使其响应方向的变化。当方向改变时,下部路径中的小部件会改变大小。 这里的问题是,上面的路线似乎比下面的路线先修建。可能情况并非如此,但是,
大小始终是先前的大小,即,我在旋转到potrait时获得景观大小,反之亦然,就好像上一条路线是在下一条路线之前建造的(我的假设)。这同样适用于该职位。我基本上得到了前面的
RenderBox


是否有任何方法可以获取小部件的当前位置,即通过
renderBox.localToGlobal(0,0)
?我想,我可以通过在
GlobalKey
具有新大小后渲染
构建页面来实现这一点。

检查此代码,告诉我它是否按照您的预期工作

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

void main() => runApp(MyApp());

StreamController<MyWidgetStatus> firstRouteStatus =
    StreamController.broadcast();

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Orination Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  GlobalKey _stateKey;
  MyWidgetStatus _status;
  double height;
  double width;

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    _stateKey = GlobalKey();

    SchedulerBinding.instance.addPostFrameCallback(_calculatePositionOffset);

    super.initState();
  }

  _calculatePositionOffset(_) {
    _status = _getPositions(_stateKey);

    firstRouteStatus.add(_status);
    print("position = ${_status.position}");
  }

  MyWidgetStatus _getPositions(_key) {
    final RenderBox renderBoxRed = _key.currentContext.findRenderObject();
    final position = renderBoxRed.localToGlobal(Offset.zero);
    final height = renderBoxRed.constraints.maxHeight;
    final width = renderBoxRed.constraints.maxWidth;
    return MyWidgetStatus(position: position, width: width, hight: height);
  }

  void didChangeMetrics() {
    print("Metrics changed");
    SchedulerBinding.instance.addPostFrameCallback(_calculatePositionOffset);
    super.didChangeMetrics();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
          child: Icon(Icons.navigate_next),
          onPressed: () {
            _settingModalBottomSheet(context);
          }),
      body: OrientationBuilder(
        builder: (context, orientation) {
          return Center(
            child: LayoutBuilder(
              builder: (context, constraints) => SizedBox(
                    key: _stateKey,
                    height: orientation == Orientation.portrait ? 100.0 : 50,
                    width: orientation == Orientation.portrait ? 50.0 : 100.0,
                    child: Container(
                      color: Colors.red,
                    ),
                  ),
            ),
          );
        },
      ),
    );
  }

  void _settingModalBottomSheet(context) {
    showModalBottomSheet(
        context: context,
        builder: (BuildContext bc) {
          return Scaffold(
            body: StreamBuilder(
              stream: firstRouteStatus.stream,
              builder: (context, AsyncSnapshot<MyWidgetStatus> snapshot) =>
                  snapshot.hasData
                      ? Container(
                          child: Text("Position = ${snapshot.data.position}"),
                        )
                      : Text("No Data"),
            ),
          );
        });
  }
}

class MyWidgetStatus {
  final Offset position;
  final double hight;
  final double width;

  MyWidgetStatus({
    this.position,
    this.hight,
    this.width,
  });
}

我有没有办法获取小部件的当前大小?
没有,根据定义,这是不可能的。你能详细解释一下你的用例吗?@RémiRousselet,具体来说,我指的是位置(我使用
renderBox.localToGlobal(0,0)
实现了这一点,我还更新了我的问题)。我想在另一个小部件的位置画一个覆盖图。你能制作一个gif来展示你想要的行为吗?为了确保我们不在XY问题@RémiRousselet中,情况可能就是这样。我只想在小部件的位置显示一个覆盖,当点击它的外部时,覆盖应该消失。我用
popurute
解决了这个问题,但是,改变方向时位置会落后,也就是说,
buildPage
中的覆盖层在
renderBox
具有新位置之前被重建。@creativecreateormormaybenot如果您想简单地限制弹出窗口的大小,我做了类似的事情,将其最大大小限制为屏幕宽度和高度的90%,另外,将其宽度限制为某个静态数字,这样看起来就不会拉伸,并使高度自动调整大小。如果这是我的目标,我将分享我的解决方案。极好的答案!我从这个答案中得到的是,这就是我所寻找的。我现在会接受这个答案,如果没有任何变化,你将自动获得赏金。然而,Rémi Rousselet指出,可能有一种完全不同的方法来解决这个问题。@CreativeCreatorMorMaybeno非常感谢,我认为您需要WidgetsBindingObserver和didChangeMetrics,因为旋转不会触发initState,回调只执行一次,我知道,您可以直接使用它从另一条路线获取位置,而无需使用流,但我更愿意这样实现,作为在集团模式中使用它的第一步,如果雷米·罗塞莱以不同的方式解决问题,那将是非常棒的。
import 'package:rxdart/rxdart.dart';
StreamController<MyWidgetStatus> firstRouteStatus =
   BehaviorSubject();
rxdart: ^0.22.0