Flutter Cookbook (Animation, Design)
Updated:
1.Animation
Animate the properties of a container
-
Container 를 사용해서 그 안의 영역의 width, height, background color, padding, borders 등 을 조절해서 만들수 있습니다
-
예시로 floting button 을 누르게 되면 container 의 크기, 색, radius 가 랜덤으로 마뀌는 animatedContainer 생성
Check point!
-
StatefulWidget 에서 default 값을 설정합니다
-
위에 default 로 선언된 값을 animatedContainer 를 사용해서 그 값을 적용합니다
-
버튼을 누를때 마다 그 값들이 바뀔 수 있도록
setState(){}
에서 각 값을 random 값으로 설정 해 줍니다
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const AnimatedContainerApp(),
);
}
}
class AnimatedContainerApp extends StatefulWidget {
const AnimatedContainerApp({Key? key}) : super(key: key);
@override
_AnimatedContainerAppState createState() => _AnimatedContainerAppState();
}
class _AnimatedContainerAppState extends State<AnimatedContainerApp> {
// 초기 변수 값 선언
double _width = 50;
double _height = 50;
Color _color = Colors.green;
BorderRadiusGeometry _borderRadius = BorderRadius.circular(8);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('AnimatedContainer Demo'),
),
body: Center(
// AnimatedContainer 생성
child: AnimatedContainer(
// 각 크기의 값을 변수 값에 대입
width: _width,
height: _height,
decoration: BoxDecoration(
color: _color,
borderRadius: _borderRadius,
),
// 얼마동안 animation 의 시간 설정함
duration: const Duration(seconds: 1),
// 에니메이션 effect 의 값을 설정합니다
curve: Curves.fastOutSlowIn,
),
),
floatingActionButton: FloatingActionButton(
// 버튼을 클릭 할 때 변수 값 설정
onPressed: () {
// setState 를 사용해서 onPressed 될때 마다 새로운 value 값이 설정 될 수 있도록 값을 설정함
setState(() {
// random 변수 값 생성
final random = Random();
// 0 ~ 300 까지의 랜덤 값이 double 형태로 나올 수 있게 함
_width = random.nextInt(300).toDouble();
_height = random.nextInt(300).toDouble();
// color 도 마찬가지로 RGBO 이 256 안에서 random 값이 나오게 설정함
_color = Color.fromRGBO(
random.nextInt(256),
random.nextInt(256),
random.nextInt(256),
1,
);
// border 값 random 값 설정
_borderRadius =
BorderRadius.circular(random.nextInt(100).toDouble());
});
},
child: const Icon(Icons.play_arrow),
),
),
);
}
}
Fade a widget in and out
- AnimatedOpacity widget 을 사용해서 투명도 에니메이션을 사용할 수 있습니다
Check point!
-
fade in and out 용 Container 생성
-
StatefulWidget 생성 및 설정
-
action button 생성 및 설정
-
Fade in and out 설정
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// bool type 의 visible 변수 생성
bool _visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Opacity Demo'),
),
body: Center(
// AnumatedOpacity 생성
child: AnimatedOpacity(
// _visible 이 true 이면 opacity 1.0 (fully visible).
// _visible 이 false 이면 opacity 0.0 (invisible).
opacity: _visible ? 1.0 : 0.0,
duration: const Duration(milliseconds: 500),
// 초록색 container 는 animatedOpacity widget 의 child 에 위치 해야 함
child: Container(
width: 200.0,
height: 200.0,
color: Colors.green,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// pressed 할때 마다 ture / false 를 변경 하는 setState
setState(() {
_visible = !_visible;
});
},
// 버튼을 길게 눌렀을때 tooltip 의 text 표시
tooltip: 'Toggle Opacity',
child: const Icon(Icons.flip),
),
);
}
}
2.Design
Add a Drawer to a screen
- 햄버거 버튼을 누르면 좌 / 우측에서 drawer 가 스크린에 나타 나게 하는 기능 만들기 입니다.
Check point!
-
Scaffold
생성하기 -
Drawer 추가하기
-
Drawer 의 items 생성하기
-
Drawer 닫기 기능 만들기
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Drawer Demo')),
body: const Center(
child: Text('My Page!'),
),
// Drawer 위젯 생성
drawer: Drawer(
// Child 로 ListView 생성
child: ListView(
// 중요!! : ListView 의 padding 사이즈는 0 으로 맞춰 야 함
padding: EdgeInsets.zero,
children: [
// DrawerHeader 색, text 설정
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('Drawer Header'),
),
ListTile(
title: const Text('Item 1'),
onTap: () {
// 클릭할때 다른 state 로 넘어 갈 수 있게 state 설정함
// 예를 들어 page1(); 하면 page1 state 로 넘어감
// 그리고 나서 drawer 를 닫기 함
Navigator.pop(context);
},
),
ListTile(
title: const Text('Item 2'),
onTap: () {
// Update the state of th 갈 수 있게 state 설정함
// 예를 들어 page2(); 하면 page2 state 로 넘어감
// 그리고 나서 drawer 를 닫기 함
Navigator.pop(context);
},
),
],
),
),
);
}
}
Display a snackbar
- 디스플레이 하단에 메세지를 띄우기 위한 기능으로 snackbar 라고 불립니다.
Check point!
-
Scaffold 생성
-
SnackBar 생성 및 설정
-
부가적인 optional action 생성
class SnackBarPage extends StatelessWidget {
const SnackBarPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SnackBar Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// snackBar 디스플레이 표시를 위한 변수 선언
final snackBar = SnackBar(
content: const Text('Yay! A SnackBar!'),
// Snackbar 의 action 버튼 생성 : SnackBarAction
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Undo 를 눌렀을 경우에 action 설정
},
),
);
// ScaffoldMessenger builder widget tree 를 연결해서 showSnackBar(snackBar) 연결해서 사용함
ScaffoldMessenger.of(context).showSnackBar(snackBar);
},
child: const Text('Show SnackBar'),
),
),
);
}
}
Update the UI based on orientation
- 사용자의 위치와의 따라 portrait, landscape mode 일때 display 의 colum 숫자가 변경되게 하기 위해
Orientation
위젯을 사용합니다
Check point!
-
GridView 에서 2개의 columns 설정 (as default setting)
-
OrientationBuilder
의 위젯을 사용하여 columns 숫자를 변경합니다 (위치 변경에 따라서 columns 의 display 숫자 다르게 설정)
class OrientationList extends StatelessWidget {
const OrientationList({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Orientation Demo')),
// OrientationBuilder 생성
body: OrientationBuilder(
// builder 의 parameter 의 context, orientation 설정
builder: (context, orientation) {
return GridView.count(
// Orientation 이 portrait 일경우 2 , landscape 일때 는 3 이 설정값이 되야 됨
crossAxisCount: orientation == Orientation.portrait ? 2 : 3,
// 100개의 List 생성 및 그것에 맞게 index 번호 생성
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline4,
),
);
}),
);
},
),
);
}
}
Work with tabs
TabController
를 사용해서 상단에 tab menu 를 만들고, 아래 body 부분에 contents 가 표시되게 state 를 연결합니다
Check point!
-
TabController
생성 -
Tabs 생성
-
각 tab 에 맞는 content 생성(주로 state 로 page routing 으로 연결 함)
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// DefaultTabController 생성
home: DefaultTabController(
// 길이는 3
length: 3,
// child 는 Scaffold 를 생성해서
child: Scaffold(
appBar: AppBar(
// appBar 밑에 bottom 위치에 TabBar Widget 에서 Tab 들의 icon text 를 설정함
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
title: const Text('Tabs Demo'),
),
// TabBarView 위젯을 통해서 body 부분에 content 작성함 (주로 State() 사용해서 다른 page 의 contents 를 연결해서 사용함)
body: const TabBarView(
children: [
Icon(
Icons.directions_car,
size: 100.0,
),
Icon(
Icons.directions_transit,
size: 100.0,
),
Icon(
Icons.directions_bike,
size: 100.0,
),
],
),
),
),
);
}
}
🔶 🔷 📌 🔑
Reference
- Flutter Cookbook - https://flutter.dev/docs/cookbookics
Leave a comment