일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- androidx
- Streaming
- 명언모음
- 1인개발자
- 공자명언
- bash
- 넷플릭스
- 소울칼리버6
- 공부집중
- jetpack compose
- Coroutine
- DART
- 오픈소스
- recyclerview
- 이모지
- 명심보감
- 파이썬
- Linux
- 좋은글필사하기
- 코틀린
- 장자명언
- 이모지메모
- Android
- kotlin
- Firebase
- Flutter
- ASMR
- 벤자민플랭클린
- FSM
- Freesound
Archives
- Today
- Total
Vintage appMaker의 Tech Blog
[Flutter] BottomNavigation을 provider로 제어. 본문
Source code or Tip/Flutter & Dart
[Flutter] BottomNavigation을 provider로 제어.
VintageappMaker 2022. 8. 26. 18:02
의외로 BottomNavigation을 쓰다보면 손이 가는 경우가 많이 발생한다. 주로,
1. 하단메뉴를 눌렀을 때, 상태에 따라 다른 반응을 보여주기(지금 화면에서 보여주고 있는가? 처음누르는가?, ...)
2. 메인화면 액션을 취하면, 하단메뉴의 상태가 변하며 이동하기(화면이동 후, 위젯의 메소드 실행 등등..)
인데, 구글링을 해도 속시원한 해결방법이 없었다.
그래서 Provider에 각 위젯의 메소드를 함수형태로 보관하여 call하는 방식을 취했다.
다음은 전체소스이다.
[전체소스]
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: (_) => GlobalState()),
],
child: MaterialApp(
title: 'Flutter 예제',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(),
),
);
}
}
// 단순 함수,변수 공유용으로 사용
class GlobalState with ChangeNotifier {
bool isBottomNavigate = true;
int nClick = 0;
// page 이동
void goPage(int n) {
isBottomNavigate = false;
nClick++;
fnPageMove(n);
}
// Function 변수들
late Function fnPageMove;
late Function fnPage2_setMesageInfo = (String s) {};
}
class _OnePage extends StatefulWidget {
@override
_OnePageState createState() {
return _OnePageState();
}
}
class _OnePageState extends State<_OnePage> with AutomaticKeepAliveClientMixin {
late GestureDetector gestureDetector;
// Setting to true will force the tab to never be disposed. This could be dangerous.
@override
bool get wantKeepAlive => true;
@override
void initState() {
return super.initState();
}
@override
Widget build(BuildContext context) {
var c = context.watch<GlobalState>();
gestureDetector = GestureDetector(
onTap: () {
c.goPage(1);
},
child: Text(
"Tab2로 이동",
style: TextStyle(fontSize: 30),
));
return gestureDetector;
}
}
class _TwoPage extends StatefulWidget {
@override
_TwoPageState createState() {
return _TwoPageState();
}
}
class _TwoPageState extends State<_TwoPage> with AutomaticKeepAliveClientMixin {
// Setting to true will force the tab to never be disposed. This could be dangerous.
@override
bool get wantKeepAlive => true;
ValueNotifier<String> _data = ValueNotifier<String>("");
late GlobalState c;
@override
void initState() {
return super.initState();
}
@override
Widget build(BuildContext context) {
// build에서 초기화해야 한다.
c = context.watch<GlobalState>();
c.fnPage2_setMesageInfo = setMessageInfo;
setDefaultInfo();
return ValueListenableBuilder(
valueListenable: _data,
builder: (ctx, String s, child) {
return GestureDetector(
onTap: () {},
child: Text(
"${s}",
style: TextStyle(color: Colors.blue, fontSize: 30),
));
});
}
void setMessageInfo(String s) {
_data.value = s;
}
void setDefaultInfo() {
if (c.isBottomNavigate == false) {
setMessageInfo("위젯 클릭으로 이동. ${c.nClick}");
c.isBottomNavigate = true;
} else {
setMessageInfo("하단메뉴로 이동.");
c.isBottomNavigate = true;
}
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
late List<Widget> _items;
late GlobalState c;
ValueNotifier<int> _param = ValueNotifier<int>(0);
@override
void initState() {
_items = [_OnePage(), _TwoPage()];
}
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
// build에서 초기화해야 한다.
c = context.watch<GlobalState>();
c.fnPageMove = _onTap;
return Scaffold(
appBar: AppBar(
title: Text("Flutter Learning"),
),
body: ValueListenableBuilder(
valueListenable: _param,
builder: (ctx, int n, child) {
return Center(child: _items[n]);
},
),
bottomNavigationBar: _showBottomNav(),
);
}
Widget _showBottomNav() {
return ValueListenableBuilder(
valueListenable: _param,
builder: (ctx, n, child) {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.abc),
label: '1',
),
BottomNavigationBarItem(
icon: Icon(Icons.numbers_rounded),
label: '2',
)
],
currentIndex: _param.value,
selectedItemColor: Colors.green,
unselectedItemColor: Colors.grey,
onTap: _onTap,
);
},
);
}
void _onTap(int index) {
_param.value = index;
if (_param.value == index && index == 1) {
c.fnPage2_setMesageInfo("현재 선택된 상태에서 click함.");
}
}
}
'Source code or Tip > Flutter & Dart' 카테고리의 다른 글
[flutter] flutter를 VSCode에서 사용 시 유용한 Extension (0) | 2022.09.16 |
---|---|
[Flutter] RSS, Github API, Markdown을 이용한 Blog 정보가져오기 (0) | 2022.09.08 |
[dart] if else 최소화를 위한 함수테이블 활용 (0) | 2022.08.25 |
[dart] dart에서 null safety check을 위한 let, apply 적용 (0) | 2022.08.19 |
[Flutter] Layoutbuilder를 이용한 반응형 UI (0) | 2022.08.15 |
Comments