私の問題
BottomNavigation を使用したいのですが、現在のナビゲーション (ナビゲーションと、足場に属するすべてのものを含む複数のページを使用したい) と選択も保持したいと考えています。PopUpMenu を使用して外側の Scaffold (次の段落で説明する「外側の scaffold」) を閉じる必要があります - ログアウト機能のために閉じます。足場で足場を使用すると、内側から外側の足場を閉じることができません。もう 1 つの問題は、Android に戻るボタンがあることです。このボタンを押すと、「backbutton-pressed-event」(Widget WillPopScope によってキャッチされる) がアプリ全体を閉じるため、アプリが閉じます。Android からこの backbutton を押すと、外側の足場だけが影響を受けるためです。タブでナビゲートする内側のもの。
現在の方法
現在のタブの状況を保存するために、BottomNavigationBarTab (PersistentTabs) の定義済みクラスを使用しています。現在、足場をベースとして使用しています。タブページにも足場を使用しているため、足場内の足場であり、上記の問題を引き起こします。だから私はWillPopScopeでアンドロイドから戻る矢印を押してアプリを閉じて問題を解決し、タブの現在のページを保存しました。ただし、内部の Scaffold (タブ内のページ) からアプリを閉じることはできません。
ベース足場
BottomNavigation と Control を含むページ
Test.shouldPop は int であり、外側の Scaffold を閉じることができるかどうかを確認するのに役立ちます。
WillPopScope(
onWillPop: () async {
if(Test.shouldPop == 0 || currentTabIndex == 0 || currentTabIndex == 2) {
return true;
}
return false;
},
child: Scaffold(
body: PersistentTabs(
currentTabIndex: currentTabIndex,
screenWidgets: [NotesHome(uid: widget.uid), AreaOverviewPage(uid: widget.uid), StatisticsHome()],
),
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: AppColors.mainAccent,
onTap: setCurrentIndex,
currentIndex: currentTabIndex,
items: [
BottomNavigationBarItem(),
BottomNavigationBarItem(),
BottomNavigationBarItem(),
],
),
),
)
永続タブ クラス
class PersistentTabs extends StatelessWidget {
const PersistentTabs({@required this.screenWidgets, this.currentTabIndex = 0});
final int currentTabIndex;
final List<Widget> screenWidgets;
List<Widget> _buildOffstageWidgets() {
return screenWidgets
.map(
(w) => Offstage(
offstage: currentTabIndex != screenWidgets.indexOf(w),
child: Navigator(
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(builder: (_) => w);
},
),
),
)
.toList();
}
@override
Widget build(BuildContext context) {
return Stack(
children: _buildOffstageWidgets(),
);
}
}
例のページ 1
このページは、このタブのホームページです。
Widget build(BuildContext context){
Test.shouldPop = 0;
double screenHeight = MediaQuery.of(context).size.height - 80;
startPagePopUpMenu _selection = startPagePopUpMenu.logout;
return FutureBuilder(
future: connectToFirebase(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return SplashScreen();
} else {
return WillPopScope(
onWillPop: () async {
Test.shouldPop = 0;
return false;
},
child: Scaffold(
body: SafeArea(
top: true,
bottom: true,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(40),
child: Container(
height: screenHeight,
child: Column(
children: [
Container(
height: 30,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"App Name",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
PopupMenuButton<startPagePopUpMenu>(
onSelected: (startPagePopUpMenu result) {
setState(() {
_selection = result;
});
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<startPagePopUpMenu>>[
PopupMenuItem<startPagePopUpMenu>(
value: startPagePopUpMenu.logout,
child: Row(
children: <Widget>[
Icon(Icons.exit_to_app_rounded),
Text(" Logout")
],
),
),
],
)
],
),
),
SizedBox(
height: 30,
),
Container(
height: screenHeight -
91 -
kBottomNavigationBarHeight,
child: StreamBuilder(
stream: database.getData(),
builder: (context, snapshotData) {
// Here's a Widget, which opens Example Page 2
})),
],
),
),
),
),
),
),
);
}
});
}
例のページ 2
このページはウィジェットで開かれています
Test.shouldPop = 1;
double screenHeight = MediaQuery.of(context).size.height - 80;
return FutureBuilder(
future: connectToFirebase(),
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
return Scaffold(
body: SafeArea(
top: true,
bottom: true,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(40),
child: Container(
height: screenHeight,
child: Column(
children: [
Container(
height: 30,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
InkWell(
onTap: () {
Test.shouldPop = 0;
Navigator.pop(context);
},
child: Row(
children: [
Icon(Icons.arrow_back_ios_rounded),
Text(
"some stuff",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
],
),
),
],
),
),
SizedBox(
height: 30,
),
Container(
height:
screenHeight - 91 - kBottomNavigationBarHeight,
child: StreamBuilder(
stream: database.getData(),
builder: (context, dataSnapshot) {
})),
],
),
),
),
),
),
);
} else {
return SplashScreen();
}
},
);
うまくいけば、すべてが理解できるか、情報が欠落している可能性があります。それ以外の場合は、お気軽にお問い合わせください! あなたの助けと努力に感謝します!