如何解决我该怎么办Navigator.push只在模式底部不是父页面
在我的应用中,我正在尝试创建评论部分。在本部分中,我希望用户能够以类似于YouTube应用程序的方式回复其他用户的评论。我设法创建了一个模态的底部工作表,其中显示了顶级注释,并且在几个流构建器的帮助下,它运行良好。但是,当前面临的问题是第二级评论(回复人们的评论。)。我要这样做,以便用户点击评论,然后转到页面(仍在模式底部)中,在该页面上他可以看到对该评论的所有回复,也可以自己发表评论,如果按回去,他会回到他原来的位置,并可以继续滚动浏览顶级评论。
类似于YouTube应用的外观。 我的想法是在底部工作表中使用Navigator.push,将新页面覆盖在模式底部工作表中当前存在的页面顶部,在此新页面中,针对特定注释的第二级注释(回复)为被显示。但是,当我调用Navigator.push时,整个页面都会更改。整个父页面将移至新页面,而不仅仅是底页中的内容。所以,这就是我的问题。我愿意接受想法。
我的注释底页后面的代码:
showModalBottomSheet(
context: context,builder: (context) {
return
Container(
child: StatefulBuilder(
builder: (BuildContext context,setTheModalState) {
setModalState = setTheModalState;
return Container(
child: Column(
children: <Widget>[
Expanded(
child: StreamBuilder(listview))])}))}
这是我到目前为止设计的。现在,棘手的一点是,只需按下回复按钮(消息图标),就可以在模式表中创建一个新页面
注释部分的代码:
showModalBottomSheet(
context: context,setTheModalState) {
setModalState = setTheModalState;
return Container(
child: Column(
children: <Widget>[
Expanded(
child: StreamBuilder(
stream: Firestore.instance
.collection("Replies")
.document(dream.documentID)
.collection(dream.documentID)
.orderBy('time',descending: true)
.snapshots(),builder: (context,snapshot) {
if (!snapshot.hasData) {
return Center(
child: SpinKitDoubleBounce(
color: Colors.blue,),);
} else {
dynamic replies = snapshot.data.documents;
return ListView.builder(
itemCount: replies.length,reverse: true,itemBuilder: (context,index) {
if (replies[index]["text"] != "" &&
replies[index]["images"] == null) {
return _buildStringCommment(
replies[index],true);
} else {
if (replies[index]["images"].length == 1) {
return _buildCommentFromOneImage(
replies[index],true);
} else {
if (replies[index]["images"].length == 2) {
return _buildCommentFromTwoImages(
replies[index],true);
} else {
if (replies[index]["images"].length ==
3) {
return _buildCommentFromThreeImages(
replies[index],true);
} else {
if (replies[index]["images"].length ==
4) {
return _buildCommentFromFourImages(
replies[index],true);
} else {
if (replies[index]["images"].length ==
5) {
return _buildCommmentFromFiveImages(
replies[index],true);
} else {
return _buildMessageFromMoreThanFiveImages(
replies[index],true);
}
}
}
}
}
}
},);
}
},theTypeReplyThingie(dream,context,true)
],);
},);
},);
“类型回复事物”是具有文本输入形式和发送按钮的小部件。
解决方法
嗨,我认为您需要在底页内进行导航,因为它会在正常页面中发生,您可以继续进行操作的一种方法是使用以下代码,一旦我希望它可以工作,就请对其进行测试。 每当需要打开工作表时,都可以调用openbottomsheet
void opensheet() async {
showModalBottomSheet(
context: (context),enableDrag: true,isDismissible: true,builder: (context) {
return Page1();
});
}
}
class Page1 extends StatefulWidget {
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
int currentview = 0;
List<Widget> pages;
@override
void initState() {
pages = [
page1(),page2(),];
super.initState();
}
@override
Widget build(BuildContext context) {
return pages[currentview];
}
Widget page1() {
return 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 = 1;
});
},child: RaisedButton(
child: Text("click to navigate"),),);
}
Widget page2() {
return Container(
decoration: BoxDecoration(
color: Colors.white,child: Center(
child: InkWell(
onTap: () {
setState(() {
currentview = 0;
});
},child: Text("click to move back"),);
}
}
要控制位于父页面底部的后退按钮,请用willpopscope将支架包围起来
willpopscope(
onwillpopscope:(){
//check if bottomsheet is open or not this may be hard to listen the state of bottomsheet let me try it
if(bottomsheetisopen){
//set the bottomsheet currentindex to 0 for initial page
return Future.value(false);
}else{
return Future.value(true);
}
}
child:Scaffold()
)
尝试使用底部工作表和模式底部工作表中的一个,可以提供一个侦听器,以监听工作表处于打开或关闭状态的情况
,您必须使用showModalBottomSheet()方法,该方法将返回所需的注释部分。
示例代码为:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,home: Scaffold(
appBar: AppBar(title: const Text(_title)),body: MyStatelessWidget(),);
}
}
/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: const Text('showModalBottomSheet'),onPressed: () {
showModalBottomSheet<void>(
context: context,builder: (BuildContext context) {
return Container(
height: 200,color: Colors.amber,child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,mainAxisSize: MainAxisSize.min,children: <Widget>[
const Text('Modal BottomSheet'),RaisedButton(
child: const Text('Close BottomSheet'),onPressed: () => Navigator.pop(context),)
],);
},);
},);
}
}
有关更多信息,请访问:https://api.flutter.dev/flutter/material/showModalBottomSheet.html
,有两种方法可以实现这一目标。
-
如果您正在使用modalSheet,那么为什么需要使用Navigator.push?可以说,您有一个注释文本字段/按钮。对于onPressed回调,您需要调用showModalSheet。您不需要路由。
`Inkwell(child: Text("comment"),onTap: () => showModalSheet() //your sheet here ) `
-
您可以在MaterialPageRoute中使用fullScreenDailog属性。这样会更适合您的要求。
Navigator.of(context).push( MaterialPageRoute( fullscreenDialog: true,builder: (context) => XYZ(),)
Soooo,为了使可能有相同查询的其他人受益,我设法使用了Azad Prajapat先生的答案的修改版本来做到这一点。我在下面附上相关代码。
从本质上讲,我使用堆栈显示高度为0的大小的框,或显示具有stream_builder,文本形式和reply_to_a_comment页面的其他相关小部件的容器。使用布尔值,我能够轻松地在用户看到的内容之间进行切换,而不必重新加载整个评论页面,也不会丢失用户当前的滚动位置。 PS:我相对来说是个入门者,所以,有些代码可能看起来太样板了。只是忍受我。
新的注释部分代码:
wereOnTopLevel = true;
showModalBottomSheet(
context: context,builder: (context) {
return Container(
child: StatefulBuilder(
builder: (BuildContext context,setTheModalState) {
setModalState = setTheModalState;
return Stack(
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Expanded(
child: StreamBuilder(
stream: Firestore.instance
.collection("Replies")
.document(post.documentID)
.collection(post.documentID)
.orderBy('time',descending: true)
.snapshots(),builder: (context,snapshot) {
if (!snapshot.hasData) {
return Center(
child: SpinKitDoubleBounce(
color: Colors.blue,);
} else {
dynamic replies = snapshot.data.documents;
return ListView.builder(
itemCount: replies.length,reverse: true,itemBuilder: (context,index) {
if (replies[index]["text"] != "" &&
replies[index]["images"] == null) {
return _buildStringReply(
replies[index],true,true);
} else {
if (replies[index]["images"].length ==
1) {
return _buildMessageFromOneImage(
replies[index],true);
} else {
if (replies[index]["images"].length ==
2) {
return _buildMessageFromTwoImages(
replies[index],true);
} else {
if (replies[index]["images"].length ==
3) {
return _buildMessageFromThreeImages(
replies[index],true);
} else {
if (replies[index]["images"]
.length ==
4) {
return _buildMessageFromFourImages(
replies[index],true);
} else {
if (replies[index]["images"]
.length ==
5) {
return _buildMessageFromFiveImages(
replies[index],true);
} else {
return _buildMessageFromMoreThanFiveImages(
replies[index],true);
}
}
}
}
}
}
},);
}
},theTypeReplyThingie(dream,context,true)
],wereOnTopLevel
? SizedBox(
height: 0,)
: showTheRepliesToCommentsThing(
dream,idYaComment,commentInfo)
],);
},);
wereOnTopLevel是一个布尔值,它告诉底页用户是否在特定评论上点击了“ replyToAComment”按钮。
theTypeReplyThing是一个小部件,其中包含textFormField,表情符号网格,用于显示所选图像网格的容器,发送按钮以及用于将图像附加到回复/评论的按钮。
showTheRepliesToTheCommentsThing是包含回复的小部件。它与注释页面大致相同,不同之处在于,我在顶部放了一个小小的预览,以回复要注释的注释,并且我不得不将容器的颜色设为白色,因为否则它是透明的且这看起来很混乱。
让我附上reply_to_a_comment页面的图像以显示不同之处。 (稍后我在顶部栏下方添加了一个分隔线。为了使其看起来更好) 将其与我附加到问题的评论部分的图像进行对比。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。