Skip to content

[Flutter] 動態增加 Row 或 Column 內的元件

Last Updated on 2021-10-14 by Clay

Flutter 中的 Row 以及 Column 能夠讓我們的元件呈現橫向或是縱向的佈局,是相當重要的佈局形式。

而介面的元件若以美感的角度來看,很難在使用者第一次進入介面時就將元件完全佈置好;更多的,則是隨著使用者的操作,在佈局介面中『動態』地新增元件。

今天我想要紀錄的,便是如何在像是 Row、Column 這類的佈局中新增不同的 Container。其中最核心的觀念便是使用函式將 List<Widget> 這種資料型態的變數(也就是說除了 Container 外其他的 Widget 也可以依此方法實作)回傳給 children 參數。緊接著,我們只需要調整 List<Widget> 中的物件,刷新介面,就可以做出動態調整物件的效果了。


程式碼解釋

接下來我會一步步介紹範例程式碼。完整、可試跑的程式碼則放在下一小節。


程式進入點

import 'dart:math';
import 'package:flutter/material.dart';


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


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


// HomePage
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}


首先,匯入必要的函式庫,建立 main() 進入點。


返回隨機顏色 Container 元件的函式

// Randomly colored Container
Container createNewContainer() {
  return Container(
    height: 100,
    width: 100,
    color: Color.fromARGB(
      255,
      Random().nextInt(256),
      Random().nextInt(256),
      Random().nextInt(256),
    ),
  );
}


為了使增加的 Container 元件做出區別,我每次建立新的 Container 元件時都會給予隨機的顏色。


_HomePageState 程式碼

這裡我宣告了以下變數以及函式:

  • containerList:一個 List<Container> 資料型態的變數,能儲存各種 Container 元件
  • addContainer():在 containerList 中增加一個隨機顏色的 Container
  • popContainer():在 containerListpop 出最後一項 Container 元件
  • _childrenList():返回 containerList 變數,給予 ColumnRow 佈局用的 children 參數

然後我在最下方設置了兩個按鈕,一個對應 addContainer()、一個對應 popContainer()

// _HomePageState
class _HomePageState extends State<HomePage> {
  // Init
  List<Container> containerList = [
    createNewContainer(),
    createNewContainer(),
  ];

  // Add
  void addContainer() {
    containerList.add(createNewContainer());
  }

  // Pop
  void popContainer() {
    containerList.removeLast();
  }

  // _childrenList
  List<Widget> _childrenList() {
    return containerList;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: _childrenList(),
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            backgroundColor: Colors.black,
            onPressed: () {
              setState(() {
                addContainer();
              });
            },
            child: Icon(Icons.add),
          ),
          SizedBox(
            height: 10,
          ),
          FloatingActionButton(
            backgroundColor: Colors.grey,
            onPressed: () {
              setState(() {
                popContainer();
              });
            },
            child: Icon(Icons.remove),
          )
        ],
      )
    );
  }
}


詳細的輸出結果可以參照下方完整程式碼的部分。


完整程式碼

import 'dart:math';
import 'package:flutter/material.dart';


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


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


// HomePage
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}


// Randomly colored Container
Container createNewContainer() {
  return Container(
    height: 100,
    width: 100,
    color: Color.fromARGB(
      255,
      Random().nextInt(256),
      Random().nextInt(256),
      Random().nextInt(256),
    ),
  );
}


// _HomePageState
class _HomePageState extends State<HomePage> {
  // Init
  List<Container> containerList = [
    createNewContainer(),
    createNewContainer(),
  ];

  // Add
  void addContainer() {
    containerList.add(createNewContainer());
  }

  // Pop
  void popContainer() {
    containerList.removeLast();
  }

  // _childrenList
  List<Widget> _childrenList() {
    return containerList;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: _childrenList(),
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            backgroundColor: Colors.black,
            onPressed: () {
              setState(() {
                addContainer();
              });
            },
            child: Icon(Icons.add),
          ),
          SizedBox(
            height: 10,
          ),
          FloatingActionButton(
            backgroundColor: Colors.grey,
            onPressed: () {
              setState(() {
                popContainer();
              });
            },
            child: Icon(Icons.remove),
          )
        ],
      )
    );
  }
}


Output:

https://clay-atlas.com/wp-content/uploads/2021/03/Screen-Recording-2021-03-09-at-1.20.29-PM.mov

References


Read More

Tags:

Leave a Reply取消回覆

Exit mobile version