gpt4 book ai didi

android - 如何在 showModalBottomSheet 中创建内部导航?

转载 作者:行者123 更新时间:2023-12-05 00:00:19 26 4
gpt4 key购买 nike

在我的应用程序中,我正在尝试实现类似 Badoo 的排序/过滤 showBottomModalSheet 功能。我设法创建了 2 个单独的页面,我可以在它们之间来回导航。但是,我面临的问题是 showBottomModalSheet 中的第二页。后退按钮工作正常,直到我尝试触摸模式之外,这会返回到第一页。相反,它应该关闭模态。

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). When back button is pressed it navigates to 1st screen until it closes modal completely. Touching outside of the modal also closes the modal

我尝试过的最佳 stackoverflow 答案:

https://stackoverflow.com/questions/63602999/how-can-i-do-navigator-push-in-a-modal-bottom-sheet-only-not-the-parent-page/63603685#63603685

我也尝试过使用 modal_bottom_sheet 包,但没有成功。 https://pub.dev/packages/modal_bottom_sheet/example

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;
});
}
}

最佳答案

解决方案1

使用标准DraggableScrollableSheet或第 3 方小部件来执行此操作,其中有很多。这里有一些来自 https://pub.dev/

  1. awesome_select
  2. backdrop_modal_route
  3. bottom_sheet_expandable_bar
  4. bottom_sheet
  5. cupertino_modal_sheet
  6. modal_bottom_sheet
  7. just_bottom_sheet
  8. sheet

解决方案2

无论如何,如果您想手动完成,我会用 Navigator.push 来完成/Navigator.pop而不是 PageRouteBuilder使用 barrierDismissible=true

它想要以下内容。查看live demo on DartPad .

Screenshot

代码如下:

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"),
),
),
),
),
);
}
}

关于android - 如何在 showModalBottomSheet 中创建内部导航?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72972937/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com