[英]How can I create inner navigation in showModalBottomSheet?
In my app I am trying to implement Badoo-like sort/filter showBottomModalSheet feature.在我的应用程序中,我正在尝试实现类似 Badoo 的排序/过滤 showBottomModalSheet 功能。 I managed to create 2 separate pages, which I can navigate back and forth.
我设法创建了 2 个单独的页面,我可以来回导航。 However, the problem I'm facing is the second page in showBottomModalSheet.
但是,我面临的问题是 showBottomModalSheet 中的第二页。 Back button works fine until I try to touch outside of the modal, which takes back to the first page.
后退按钮工作正常,直到我尝试触摸模式之外,这会返回到第一页。 Instead it should close modal.
相反,它应该关闭模式。
User navigates to sort users modal, which shows the 1st page in showBottomModalSheet When user taps "Show gender" it navigates to the second page (the one with different genders).用户导航到排序用户模式,在 showBottomModalSheet 中显示第一页当用户点击“显示性别”时,它导航到第二页(具有不同性别的页面)。 When back button is pressed it navigates to 1st screen until it closes modal completely.
当按下后退按钮时,它会导航到第一个屏幕,直到它完全关闭模式。 Touching outside of the modal also closes the modal
在模态之外触摸也会关闭模态
The best stackoverflow answer that I tried:我试过的最好的stackoverflow答案:
https://stackoverflow.com/questions/63602999/how-can-i-do-navigator-push-in-a-modal-bottom-sheet-only-not-the-parent-page/63603685#63603685 https://stackoverflow.com/questions/63602999/how-can-i-do-navigator-push-in-a-modal-bottom-sheet-only-not-the-parent-page/63603685#63603685
I also tried using modal_bottom_sheet package, but had no luck.我也尝试使用 modal_bottom_sheet 包,但没有运气。 https://pub.dev/packages/modal_bottom_sheet/example
https://pub.dev/packages/modal_bottom_sheet/example
Most of my code behind showBottomModalSheet:我在 showBottomModalSheet 后面的大部分代码:
class Page1 extends StatefulWidget {
const Page1({
Key? key
}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
int _currentView = 0;
late List<Widget> pages;
@override
void initState() {
pages = [
page1(),
page2(),
];
super.initState();
}
@override
Widget build(BuildContext context) {
print("LOG build _currentView ${_currentView}");
return pages[_currentView];
}
Widget page1() {
return WillPopScope(
onWillPop: () async {
return true;
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(60), topLeft: Radius.circular(60))),
height: 400,
width: double.maxFinite,
child: Center(
child: Column(
children: [
Text("First page"),
ElevatedButton(
onPressed: () {
setState(() {
_currentView = 1;
print("LOG page1 _currentView ${_currentView}");
});
},
child: Text("tap to navigate to 2nd page"),
),
],
)),
));
}
Widget page2() {
return WillPopScope(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(60), topLeft: Radius.circular(60))),
height: 400,
width: double.maxFinite,
child: Center(
child: InkWell(
onTap: () {
setState(() {
_currentView = 0;
print("LOG page2 _currentView ${_currentView}");
});
},
child: Text("tap to navigate to 1st screen"),
),
),
),
onWillPop: () async {
print("LOG currentView jot $_currentView");
if (_currentView == 0) {
return true;
}
setState(() {
_currentView = 0;
});
return false;
});
}
}
Use a 3rd-party widget to do it, there are a bunch of them.使用 3rd-party 小部件来做到这一点,它们有很多。 Here are some from https://pub.dev/
这里有一些来自https://pub.dev/
Anyway, if you'd like to do it manually I'd do it with Navigator.push / Navigator.pop instead with PageRouteBuilder with barrierDismissible=true
.无论如何,如果你想手动完成,我会用Navigator.push / Navigator.pop代替PageRouteBuilder和
barrierDismissible=true
。
It would like the following.它想要以下内容。 Check out the live demo on DartPad .
查看DartPad 上的现场演示。
Here's the code:这是代码:
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 MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void _show() async {
await Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
barrierDismissible: true,
pageBuilder: (_, __, ___) => const Page1(),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _show,
tooltip: 'Settings',
child: const Icon(Icons.settings),
),
);
}
}
class Page1 extends StatefulWidget {
const Page1({Key? key}) : super(key: key);
@override
State<Page1> createState() => _Page1State();
}
class _Page1State extends State<Page1> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(60), topLeft: Radius.circular(60)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3), // changes position of shadow
),
],
),
height: 400,
width: double.maxFinite,
child: Center(
child: Material(
type: MaterialType.transparency,
child: Column(
children: [
const Text("First page"),
ElevatedButton(
onPressed: () async {
final backButton =
await Navigator.of(context).push<bool?>(
PageRouteBuilder(
opaque: false,
barrierDismissible: true,
pageBuilder: (_, __, ___) => const Page2(),
),
);
if (backButton == null || backButton == false) {
if (mounted) Navigator.of(context).pop();
}
},
child: const Text("tap to navigate to 2nd page"),
),
],
),
),
),
),
),
],
);
}
}
class Page2 extends StatelessWidget {
const Page2({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(60), topLeft: Radius.circular(60)),
),
height: 400,
width: double.maxFinite,
child: Center(
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () => Navigator.of(context).pop(true),
child: const Text("tap to navigate to 1st screen"),
),
),
),
),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.