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 中增加一個隨機顏色的 ContainerpopContainer()
:在 containerList 中pop
出最後一項 Container 元件_childrenList()
:返回 containerList 變數,給予 Column 或 Row 佈局用的 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:
References
- https://stackoverflow.com/questions/51605131/how-to-add-the-widgets-dynamically-to-column-in-flutter/51610046
- https://stackoverflow.com/questions/56335114/dynamically-add-widgets-to-a-columns-children-in-flutter