【问题标题】:How to position button in stack如何在堆栈中定位按钮
【发布时间】:2020-08-18 08:44:36
【问题描述】:

我最近正在尝试在 Flutter 中创建 UI。我创建了一个包含多个小部件(图表、子图表等)的堆栈。我想展示的最后一个小部件是一个凸起的按钮。必须像下图那样放置。我使用了一个卡片小部件,它有一个堆栈,里面有几个小部件。我把我的按钮放在这个堆栈中,以便在卡片下显示它。但是按钮必须是溢出卡,如下图所示:

我用于卡片小部件的代码:

Widget _buildCard(BuildContext context) {
    return Center(
      child: Card(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(15),
          side: BorderSide(color: Colors.blueGrey, width: 0.5),
        ),
        child: Container(
          height: MediaQuery.of(context).size.height * .65,
          width: MediaQuery.of(context).size.width * .80,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(
                  "Genel Durum",
                  style: TextStyle(
                    fontSize: 20,
                    color: Colors.black,
                    letterSpacing: 0.3,
                  ),
                ),
              ),
              Divider(
                color: Colors.grey,
                thickness: 0.3,
                endIndent: 10,
                indent: 10,
              ),
              Stack(
                children: [
                  Expanded(
                    child: _buildChart(dataList),
                  ),
                ],
              ),
              SizedBox(
                height: 20,
              ),
              _buildSubGraph(),
              SizedBox(
                height: 40,
              ),
              Positioned(top: 50, left: 50, child: _buildDetailsButton()),
            ],
          ),
        ),
      ),
    );
  }

我用于按钮的代码:

Widget _buildDetailsButton() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Expanded(
          child: ButtonTheme(
            height: 50,
            minWidth: 100,
            child: RaisedButton(
              onPressed: () {},
              color: Colors.white24,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(30),
              ),
              child: Text("Detayları Gör"),
            ),
          ),
        ),
      ],
    );
  }

这是我尝试调试应用程序时得到的结果:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a
RenderObject, which has been set up to accept ParentData of incompatible type StackParentData.
Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically,
Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a Stack widget.
The ownership chain for the RenderObject that received the incompatible parent data was:
  CustomPaint ← AnimatedCircularChart ← Container ← Expanded ← Stack ← Column ← ConstrainedBox ←
Container ← Semantics ← DefaultTextStyle ← ⋯
When the exception was thrown, this was the stack:

编辑:目前仍然无法实现我的目标。我无法在图像上创建必要的图像。当我的按钮试图溢出我的卡时,它会因为再次溢出而出错。这是我使用的新代码:

Widget _buildCard(BuildContext context) {
    return Center(
      child: Card(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(15),
          side: BorderSide(color: Colors.blueGrey, width: 0.5),
        ),
        child: Container(
          height: MediaQuery.of(context).size.height * .65 + 10,
          width: MediaQuery.of(context).size.width * .80,
          child: Stack(
            fit: StackFit.expand,
            overflow: Overflow.visible,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      "Genel Durum",
                      style: TextStyle(
                        fontSize: 20,
                        color: Colors.black,
                        letterSpacing: 0.3,
                      ),
                      textAlign: TextAlign.center,
                    ),
                  ),
                  Divider(
                    color: Colors.grey,
                    thickness: 0.3,
                    endIndent: 10,
                    indent: 10,
                  ),
                  _buildChart(dataList),
                  SizedBox(
                    height: 20,
                  ),
                  _buildSubGraph(),
                  SizedBox(
                    height: 30,
                  ),
                  Positioned(right: 0, left: 0, bottom: -1,child: Expanded(child: _buildDetailsButton())),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

【问题讨论】:

    标签: flutter user-interface dart


    【解决方案1】:

    定位应在 Stack 小部件下。并且 Expanded 不应在 Stack Widget

    将按钮添加到卡片底部。

    final double buttonHeight = 50;
    
    Widget _buildCard(BuildContext context) {
      return Center(
        child: Container(
          height: 200 + buttonHeight,
          child: Stack(
            alignment: Alignment.center,
            overflow: Overflow.visible,
            // although the overflow button is visible, but it's overflow part will not be clickable.
            // to solve this, set the height of the container to be larger enough to include the button.
            children: [
              Card(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                  side: BorderSide(color: Colors.blueGrey, width: 0.5),
                ),
                child: Container(
                  height: MediaQuery.of(context).size.height * .65,
                  width: MediaQuery.of(context).size.width * .80,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisSize: MainAxisSize.max,
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                          "Genel Durum",
                          style: TextStyle(
                            fontSize: 20,
                            color: Colors.black,
                            letterSpacing: 0.3,
                          ),
                        ),
                      ),
                      Divider(
                        color: Colors.grey,
                        thickness: 0.3,
                        endIndent: 10,
                        indent: 10,
                      ),
    //                  Expanded(
    //                    // Remove the Stack widget? seems redundant
    //                    child: _buildChart(dataList),
    //                  ),
                      SizedBox(
                        height: 20,
                      ),
    //                  _buildSubGraph(),
                      SizedBox(
                        height: 40,
                      ),
                    ],
                  ),
                ),
              ),
              Positioned(
                  bottom: -buttonHeight / 2,
                  child:
                      _buildDetailsButton()), // Positioned should be place under the Stack Widget
            ],
          ),
        ),
      );
    }
    
    Widget _buildDetailsButton() {
      return ButtonTheme(
        height: 50,
        minWidth: 100,
        child: RaisedButton(
          onPressed: () {},
          color: Colors.white24,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(30),
          ),
          child: Text("Detayları Gör"),
        ),
      );
    }
    
    
    

    【讨论】:

    • 感谢您的信息!我会尽快尝试您的解决方案。
    • 我看到另一个箭头,上面写着“底部溢出 94 像素”。
    • 只增加Container的高度
    • 感谢它的工作,我添加了底部属性以获取详细信息按钮小部件,因为顶部属性对我不起作用。
    【解决方案2】:

    您必须在堆栈小部件中使用位置小部件

    定位小部件必须是堆栈的后代,并且路径从 定位到其封闭堆栈的小部件必须仅包含 StatelessWidgets 或 StatefulWidgets(不是其他类型的小部件,例如 RenderObjectWidgets)。

    Stack(
        children: [
            MyWidget(),
            Positioned(
                bottom: 20,
                left: 20,
                child: MyWidget(color: Colors.blue),
            ),
            Positioned(
                top: 50,
                right: 50,
                child: MyWidget(color: Colors.red)
            )
        ]
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2020-11-05
      • 2022-07-14
      相关资源
      最近更新 更多