Flutter BottomNavigationBar의 탭 간 전환을 수행하는 방법
14066 단어 공급자state_notifierDartFlutter
전치
Flutter의 BottomNavigationBar를 사용하여 탭 간 전환을 구현하는 방법에 4고 8을 썼습니다.
그 구현 방법을 공유합니다.
아래 그림과 같이 탭 A-화면 1에서 탭 B-화면 2로 전환하고 싶은 경우가 없습니까?
또, 탭 B-화면 2로부터 돌아올 때에는, 탭 A-화면 1이 아니고 탭 B-화면 1로 돌아가고 싶다고 생각했습니다.
주제
Pages API를 state_notifier를 사용하여 구현했습니다.
Pages API에의 사용 방법에 대해서는, 아래의 기사가 참고로 했습니다.
state_notifier의 사용 방법에 대해서는, 아래의 기사를 참고로 했습니다.
그럼, 구현 방법을 자세하게 설명합니다.
State 정의
state_notifier 에 보관 유지하는 State(상태)가 되는 클래스를 정의합니다.
속성으로 갖는 것은 다음 항목입니다.
Pages API를 state_notifier를 사용하여 구현했습니다.
Pages API에의 사용 방법에 대해서는, 아래의 기사가 참고로 했습니다.
state_notifier의 사용 방법에 대해서는, 아래의 기사를 참고로 했습니다.
그럼, 구현 방법을 자세하게 설명합니다.
State 정의
state_notifier 에 보관 유지하는 State(상태)가 되는 클래스를 정의합니다.
속성으로 갖는 것은 다음 항목입니다.
구현 이미지는 아래와 같습니다.
enum BottomTab {
タブ1,
タブ2,
}
@freezed
class RouteState with _$RouteState {
const factory RouteState({
required BottomTab 選択中のタブ,
@Default([]) List<Page> タブ1ページ一覧,
@Default([]) List<Page> タブ2ページ一覧,
}) = _RouteState;
}
실제 구현 샘플은 여기입니다.
State의 값은 다음과 같이 변경됩니다.
초기 상태 (탭 1-화면 1이 표시됨)
속성 이름
속성 값
선택한 탭
탭 1
탭 1 페이지 일람
[]
탭 2 페이지 일람
[]
탭 2를 누르십시오 (탭 2 - 화면 1이 표시됨)
속성 이름
속성 값
선택한 탭
탭 2
탭 1 페이지 일람
[]
탭 2 페이지 일람
[]
화면 2를 누르십시오 (탭 2 - 화면 2가 표시됨)
속성 이름
속성 값
선택한 탭
탭 2
탭 1 페이지 일람
[]
탭 2 페이지 일람
[탭 2-화면 2]
Notifier 정의
State를 갱신하는 Notifier를 아래와 같이 정의합니다.
class RouteStateNotifier extends StateNotifier<RouteState> with LocatorMixin {
RouteStateNotifier() : super(const RouteState(tab: initialTab));
Future changeIndex(BottomTab tab) async {
// 選択中のタブを切り替える
}
Future push(BottomTab tab, Page page) async {
// ページ一覧の末尾にページを追加する
}
Future pop(BottomTab tab) async {
// ページ一覧の末尾のページを取り除く
}
Future replace(BottomTab tab, List<Page> pages) async {
// ページ一覧のまるっと入れ替える
}
}
Navigator 정의
State의 저장된 페이지 목록을 화면에 표시하기 때문에 Navigator의 페이지에 전달합니다.
class ProjectsNavigator extends StatelessWidget {
@override
Widget build(BuildContext context) {
final pages = context.select((RouteState state) => state.タブ2ページ一覧);
return Navigator(
pages: [
タブ2-画面1(divisionId: divisionId!, openDrawer: _openDrawer),
...pages
],
);
}
}
BottomNavigationBar 구현
BottomNavigationBar와 State를 연결합니다.
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final tab = context.select((RouteState state) => state.選択中のタブ);
final index = tab.getIndex();
return WillPopScope(
child: Scaffold(
body: IndexedStack(
index: index,
children: _children,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: index,
items: _tabItems,
onTap: (int index) {
final tab = BottomTabExt.getTab(index);
final notifier = context.read<RouteStateNotifier>();
if (tab != context.read<RouteState>().tab) {
notifier.changeIndex(tab);
}
},
),
),
);
}
}
화면 전환 구현
나중에 Notifier를 통해 State를 업데이트하여 화면 전환을 실현할 수 있습니다.
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Future _onPressedProjectDetail() async {
final notifier = context.read<RouteStateNotifier>();
await notifier.changeIndex(BottomTab.タブ2);
await notifier.replace(BottomTab.タブ2, [
タブ2-画面2(),
]);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: _onPressedProjectDetail,
child: const Text('タブ2-画面2へ'),
),
],
),
),
);
}
}
비고
그 외, 화면 천이로 구애된 점의 메모입니다.
이 변의 구현 샘플은, 하기 클래스에 집약되고 있습니다.
탭 상태 유지
IndexedStack을 사용하여 탭 상태를 유지합니다.
다만, 보통으로 실장해 버리면 부모가 빌드되는 타이밍으로 아이의 탭 모두가 빌드되어 버립니다.
그래서 초기 상태는 LoadingScreen을 유지하고 탭이 불린 타이밍에 본명의 탭(ProjectsNavigator)으로 교체한다는 것을 하고 있습니다.
선택한 탭 누르기
선택한 탭을 누르면 첫 화면으로 돌아갑니다.
(예: 탭 2-화면 2를 표시하고 있는 상태에서 탭 2가 눌러지면 탭 2-화면 1로 돌아갑니다.)
Android 뒤로 버튼 지원
WillPopScope를 사용하여 뒤로 버튼을 누르면 아래와 같이 동작하도록 하고 있습니다.
탭 2-화면 2가 표시되면, 탭 2-화면 1로 되돌아간다.
탭 2-화면 1이 표시되면 탭 1-화면 1로 돌아갑니다.
탭 1 - 화면 1이 표시되면 앱을 닫습니다.
가로 스와이프 대응
탭 1-화면 1이나 탭 2-화면 1 등 탭 내의 선두의 화면에서 가로 스와이프한 경우는, Drawer를 표시하고 싶습니다만, 탭 2-화면 2등 천이처에 있는 경우는, 가로 스와이프로 전의 화면으로 돌아가고 싶습니다.
그 때문에,
drawerEnableOpenDragGesture
라고 하는 프로퍼티을 State에 맞추어 제어하고 있습니다.
Reference
이 문제에 관하여(Flutter BottomNavigationBar의 탭 간 전환을 수행하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/urbsny/items/d04270d565e879d37622텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)