【问题标题】:Flutter - Overlay card widget on a containerFlutter - 容器上的叠加卡片小部件
【发布时间】:2018-08-30 08:47:57
【问题描述】:

在颤振中,是否可以将卡片的一部分放在另一个容器上?在 CSS 中,我们会将 margin-top 设置为负值或使用 translate 属性。由于我们无法为 margin-top 设置负值,因此有其他替代方法吗?

【问题讨论】:

  • 对于您的问题“这可能吗?”,当然可以。你试过什么?
  • 我尝试过使用堆栈小部件..但无法仅将小部件的一部分覆盖在另一个小部件上..

标签: flutter dart flutter-layout overlay flutter-widget


【解决方案1】:

是的,您可以使用Stack 小部件来实现它。您可以在背景上堆叠卡片并提供顶部或底部填充。

一个简单的例子如下:

class StackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Stack(
      children: <Widget>[
        // The containers in the background
        new Column(
          children: <Widget>[
            new Container(
              height: MediaQuery.of(context).size.height * .65,
              color: Colors.blue,
            ),
            new Container(
              height: MediaQuery.of(context).size.height * .35,
              color: Colors.white,
            )
          ],
        ),
        // The card widget with top padding, 
        // incase if you wanted bottom padding to work, 
        // set the `alignment` of container to Alignment.bottomCenter
        new Container(
          alignment: Alignment.topCenter,
          padding: new EdgeInsets.only(
              top: MediaQuery.of(context).size.height * .58,
              right: 20.0,
              left: 20.0),
          child: new Container(
            height: 200.0,
            width: MediaQuery.of(context).size.width,
            child: new Card(
              color: Colors.white,
              elevation: 4.0,
            ),
          ),
        )
      ],
    );
  }
}

上述代码的输出如下所示:

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    为此,您在 Flutter 中使用 Stack 小部件实现卡片的 Positioned

    Stack 类在您想以简单的方式重叠多个子项时很有用,

    Positioned 小部件,用于控制 Stack 的子元素的位置。

    注意:堆栈按顺序绘制其子级,第一个子级位于底部。

    ?所以让我们开始吧,不要浪费时间我们如何做到这一点。

    创建一个Stack 小部件并将其包装在Positioned 小部件中,以便为其提供正确的位置并根据需要设置小部件位置。

      @override
      Widget build(BuildContext context) {
        return new Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Positioned(
              top: 0,
              child: Container(
                color: Colors.deepPurple,
                width: MediaQuery.of(context).size.width,
                height: MediaQuery.of(context).size.height * .35,
              ),
            ),
            Positioned(
              top: MediaQuery.of(context).size.height * .25,
              left: 15,
              right: 15,
              child: Card(
                elevation: 8,
                color: Colors.white,
                shape:
                    RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
                child: Container(
                  width: MediaQuery.of(context).size.height * .90,
                  height: 220,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Icon(
                            Icons.scanner,
                            color: Colors.deepPurple,
                            size: 45,
                          ),
                          Text("SCAN QR")
                        ],
                      ),
                      Container(
                        height: 100,
                        width: 2,
                        color: Colors.deepPurple,
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                       children: <Widget>[
                         Icon(
                           Icons.bluetooth,
                           color: Colors.deepPurple,
                           size: 45,
                         ),
                         Text("BEACON")
                       ],
                      )
    
                    ],
                  ),
                ),
              ),
            ),
          ],
        );
      }
    

    【讨论】:

      【解决方案3】:

      截图:

      您应该使用Align,而不是硬编码PositionedContainer

      代码:

      @override
      Widget build(BuildContext context) {
        final size = MediaQuery.of(context).size;
        return Scaffold(
          body: Stack(
            children: [
              Column(
                children: [
                  Expanded(flex: 2, child: Container(color: Colors.indigo)),
                  Expanded(child: Container(color: Colors.white)),
                ],
              ),
              Align(
                alignment: Alignment(0, 0.5),
                child: Container(
                  width: size.width * 0.9,
                  height: size.height * 0.4,
                  child: Card(
                    elevation: 12,
                    child: Center(child: Text('CARD', style: Theme.of(context).textTheme.headline2)),
                  ),
                ),
              ),
            ],
          ),
        );
      }
      

      【讨论】:

      • 这似乎是最好的答案。你的意思是其他人没有反应,因为这个是对的?我来自 HTML、CSS、Bootstrap,所以我真的不喜欢硬编码任何布局,除非这是唯一的选择。
      • 顺便说一句,嵌套堆栈没问题吧?假设我想为我的用户头像在卡片顶部伸出一个小半圈,如下所示:stackoverflow.com/questions/51343527/…
      • @mLstudent33 是的,在 Flutter 中这样的嵌套不是问题。
      【解决方案4】:

      这里是覆盖的运行示例:

      class _MyHomePageState extends State<MyHomePage> {
           double _width = 0.0;
           double _height = 0.0;
      
           @override
           Widget build(BuildContext context) {
            _width = MediaQuery.of(context).size.width;
            _height = MediaQuery.of(context).size.height;
            return Scaffold(
             backgroundColor: Colors.white,
             body: Stack(
              children: <Widget>[
                // The containers in the background and scrollable
               getScrollableBody(),
      
               // This container will work as Overlay
               getOverlayWidget()
              ],
            ),
         );
       }
      
       Widget getOverlayWidget() {
         return new Container(
           alignment: Alignment.bottomCenter,
           child: new Container(
            height: 100.0,
            width: _width,
            color: Colors.cyan.withOpacity(0.4),
           ),
         );
       }
       Widget getScrollableBody() {
        return SingleChildScrollView(
          child: new Column(
            children: <Widget>[
              new Container(
               height: _height * .65,
               color: Colors.yellow,
             ),
             new Container(
               height: _height * .65,
               color: Colors.brown,
             ),
             new Container(
              margin: EdgeInsets.only(bottom: 100.0),
              height: _height * .65,
              color: Colors.orange,
             ),
           ],
         ),
        );
       }
      }
      

      这是代码的结果: Scrollable Body under customised Bottom Bar

      【讨论】:

        猜你喜欢
        • 2022-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-13
        • 1970-01-01
        • 2022-07-20
        • 1970-01-01
        • 2022-12-05
        相关资源
        最近更新 更多