Skip to content

[Flutter] 使用 Stack 佈局讓元件重疊

Last Updated on 2021-10-16 by Clay

最近一直在研究在 Flutter 中,該如何建造如下圖這般擁有重疊形狀的底部按鈕:

研究之後才發現,Flutter 有提供一種叫做 Stack 的元件佈局,可以讓不同的元件彼此重疊。於是,今天就簡單紀錄如何使用 Stack 佈局元件。


Flutter 中的 Stack 佈局元件

Stack 佈局元件,顧名思義便是一個『堆疊』的動作。越早建立的元件便在越下方,元件之間不會互相卡到彼此的位置,是一層層疊上去的佈局型態。

以下是段簡單的範例程式碼。

import 'package:flutter/material.dart';

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

// MyApp
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ContainerStack(),
    );
  }
}

// ContainerStack
class ContainerStack extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Container(
              width: 300,
              height: 300,
              color: Colors.red,
            ),
            Container(
              width: 200,
              height: 200,
              color: Colors.orange,
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.yellow,
            ),
          ],
        ),
      ),
    );
  }
}


Output:

不過要注意的是,如果後來堆疊上的元件比底下的元件來得面積更大,是會把下面的元件蓋住的!

另外,既然都寫了,也順便紀錄我所寫的底部按鈕程式:

import 'package:flutter/material.dart';

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

// MyApp
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ContainerStack(),
    );
  }
}

// ContainerStack
class ContainerStack extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        alignment: Alignment.bottomCenter,
        children: <Widget>[
          Container(
            width: MediaQuery.of(context).size.width,
            height: 50,
            color: Colors.grey[800],
          ),
          Container(
            alignment: Alignment.bottomRight,
            child: ClipOval(
                child: Material(
              color: Colors.black, // button color
              child: Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(
                    Radius.circular(50.0),
                  ),
                  border: Border.all(
                    color: Colors.grey,
                    width: 4.0,
                  ),
                ),
                child: InkWell(
                  splashColor: Colors.grey, // inkwell color
                  child: SizedBox(
                      width: 75,
                      height: 75,
                      child: Icon(
                        Icons.add,
                        color: Colors.white,
                        size: 60,
                      )),
                  onTap: () {},
                ),
              ),
            )),
          ),
        ],
      ),
    );
  }
}


Output:

我喜歡這樣的底部狀態欄,比單調的全部都是正方形的按鈕好多了。


References


Read More

Tags:

Leave a Reply