일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 코틀린
- ASMR
- 벤자민플랭클린
- kotlin
- FSM
- 명심보감
- 공부집중
- Android
- bash
- 이모지
- androidx
- 이모지메모
- 좋은글필사하기
- 공자명언
- Firebase
- Linux
- 파이썬
- DART
- recyclerview
- jetpack compose
- 소울칼리버6
- Coroutine
- 넷플릭스
- Freesound
- 명언모음
- 장자명언
- Flutter
- Streaming
- 오픈소스
- 1인개발자
Archives
- Today
- Total
Vintage appMaker의 Tech Blog
[Flutter] BottomNavitaionBar에서 화면이동시 코드실행(화면갱신) 본문
Source code or Tip/Flutter & Dart
[Flutter] BottomNavitaionBar에서 화면이동시 코드실행(화면갱신)
VintageappMaker 2022. 7. 20. 11:49
BottomNavigationBar를 통해 하단 버튼을 누르며 메인화면을 갱신하다보면 선택 화면이 표시된 후, 특정 작업을 수행해야 하는 경우가 종종 발생한다. 이럴경우, Flutter는 선언형 구조이기 때문에 Native 프로그래밍에 비해 불편한 부분이 있다. 그래서 Provider를 사용하여 코드를 깔금하게 정리하는 것을 권장되고 있다.
- 화면갱신완료 시점
- provider로 데이터 처리
- 객체의 메소드 실행(권장하지 않지만 사용할 경우가 있다)
- 화면갱신 완료시점
WidgetsBinding.instance.addPostFrameCallback()을 사용한다. 주로 stateful 위젯의 initState()에서 구현해준다.
저 함수의 파라메토로 종료시 실행될 콜백을 구현하면 된다.
- provider로 데이터 처리
위젯간 계층관계가 있고 위젯변환시 데이터가 공유되어야 한다면 고민없이 provider를 사용하기를 권장한다.
- 객체의 메소드 실행(권장하지 않지만 사용할 경우가 있다)
Flutter는 선언형 프로그래밍이라 화면에 표시되는 Widget을 객체로 관리하는 것을 권장하지 않는다. 그럼에도 불구하고 특정위젯의 메소드를 직접 실행하기 위해서는 명명된 object로 변수처리 되어야 한다. 그럴 경우, build 메소드에 넘겨질 Widget을 변수로 선언 후 관리하면 된다. 단, 변수를 액세스하려면 화면갱신이 완료된 시점에만 가능하다.
결국, WidgetsBinding.instance.addPostFrameCallback()에서 처리해야한다.
[전체소스]
import "package:flutter/material.dart";
import "package:flutter/widgets.dart";
import "package:provider/provider.dart";
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
],
child: MaterialApp(
title: 'Flutter 예제',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(),
),
);
}
}
class Counter with ChangeNotifier {
static int initsize = 15;
int _count = initsize;
bool isOnTapBefore = false;
int get fontsize => _count;
void increment() {
_count++;
isOnTapBefore = true;
notifyListeners();
}
void reset() {
_count = initsize;
isOnTapBefore = false;
notifyListeners();
}
}
class OnePage extends StatefulWidget {
@override
_OnePageState createState() {
return _OnePageState();
}
}
class _OnePageState extends State<OnePage> {
late GestureDetector gestureDetector;
@override
void initState() {
// 위젯바인딩 완료
WidgetsBinding.instance.addPostFrameCallback((_) {
print("화면갱신");
// 1.5초 후 tap하기
Future.delayed(Duration(milliseconds: 1500))
.then((onValue) => gestureDetector.onTap?.call());
});
return super.initState();
}
@override
Widget build(BuildContext context) {
var c = context.watch<Counter>();
gestureDetector = GestureDetector(
onTap: () {
context.read<Counter>().increment();
},
child: (c.isOnTapBefore)
? Text(
"click me!(${c.fontsize})",
style: TextStyle(fontSize: c.fontsize.toDouble()),
)
: Image.network(
"https://thumbs.dreamstime.com/b/click-here-button-hand-icon-vector-web-sign-cursor-symbol-isolated-152282340.jpg"),
);
return gestureDetector;
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
double fontSize = 15;
late List<Widget> _items;
@override
void initState() {
_items = [
OnePage(),
Text(
'2',
),
Text(
'3',
),
];
}
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter Learning"),
),
body: Center(child: _items[_selectedIndex]),
bottomNavigationBar: _showBottomNav(),
);
}
Widget _showBottomNav() {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.abc),
label: '1',
),
BottomNavigationBarItem(
icon: Icon(Icons.numbers_rounded),
label: '2',
),
BottomNavigationBarItem(
icon: Icon(Icons.numbers_sharp),
label: '3',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.green,
unselectedItemColor: Colors.grey,
onTap: _onTap,
);
}
void _onTap(int index) {
_selectedIndex = index;
if (index == 0) {
//context.read<Counter>().reset();
context.read<Counter>().reset();
}
// 화면갱신
setState(() {});
}
}
'Source code or Tip > Flutter & Dart' 카테고리의 다른 글
[Flutter] Autocomplete 커스텀 (0) | 2022.07.22 |
---|---|
[Flutter] BottomNavitaionBar에서 backkey처리( WillPopScope ) (0) | 2022.07.21 |
[Flutter] Draggable Floating 위젯 예제 (0) | 2022.07.15 |
[Flutter] LimitedBox 예제 - 최대크기를 고정한 스크롤 화면 (0) | 2022.07.13 |
[Flutter] 기초 - 화면끼리 데이터 전달(반환) 예제 (0) | 2022.07.11 |
Comments