如何在 List 小部件 Flutter 中无上下文导航
Posted
技术标签:
【中文标题】如何在 List 小部件 Flutter 中无上下文导航【英文标题】:How to navigate without context in List widget Flutter 【发布时间】:2021-12-04 00:36:47 【问题描述】:我正在开发一个 Flutter Web 应用程序,在该应用程序中我开发了自定义导航栏,但我正在努力在导航栏项目中添加导航。我尝试在没有上下文的情况下进行导航,但不幸的是它不适用于我创建的列表。我确实尝试过创建函数并根据需要放置导航,但仍然没有运气。
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:get/get.dart';
import 'package:shimmer/shimmer.dart';
import 'package:customweb/about.dart';
double collapsableHeight = 0.0;
Color selected = Color(0xffffffff);
Color notSelected = Color(0xafffffff);
class Nav extends StatefulWidget
@override
_NavState createState() => _NavState();
class _NavState extends State<Nav>
@override
Widget build(BuildContext context)
double width = MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
body: Stack(
children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: EdgeInsets.only(top: 250),
child: Image.asset(
"assets/logo.png",
scale: 2,
)),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 120),
child: Text(
"Download now available on",
style: TextStyle(fontSize: 30),
))),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(right: 200, bottom: 50),
child: Image.asset(
"assets/1200px-Google_Play_Store_badge_EN.png",
scale: 8,
))),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(left: 200, bottom: 50),
child: Image.asset(
"assets/1200px-Download_on_the_App_Store_Badge.png",
scale: 8,
))),
AnimatedContainer(
margin: EdgeInsets.only(top: 79.0),
duration: Duration(milliseconds: 375),
curve: Curves.ease,
height: (width < 800.0) ? collapsableHeight : 0.0,
width: double.infinity,
color: Color(0xff121212),
child: SingleChildScrollView(
child: Column(
children: navBarItems,
),
),
),
Container(
color: Colors.amber,
height: 80.0,
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AnimatedTextKit(
animatedTexts: [
FadeAnimatedText(
'Get It',
textStyle: TextStyle(fontSize: 26, color: Colors.white),
),
FadeAnimatedText(
'All Amazing Stuff',
textStyle: TextStyle(fontSize: 22, color: Colors.white),
),
FadeAnimatedText(
'One Platform',
textStyle: TextStyle(fontSize: 24, color: Colors.white),
),
FadeAnimatedText(
'Endless Services',
textStyle: TextStyle(fontSize: 24, color: Colors.white),
),
FadeAnimatedText(
'Available Soon',
textStyle: TextStyle(fontSize: 24, color: Colors.white),
),
],
onTap: ()
print("");
,
),
LayoutBuilder(builder: (context, constraints)
if (width < 800.0)
return NavBarButton(
onPressed: ()
if (collapsableHeight == 0.0)
setState(()
collapsableHeight = 240.0;
);
else if (collapsableHeight == 240.0)
setState(()
collapsableHeight = 0.0;
);
,
);
else
return Row(
children: navBarItems,
);
)
],
),
),
],
),
),
);
List<Widget> navBarItems = [
NavBarItem(
text: 'About',
onPressed: ()
Get.to(AboutPage());
,
),
NavBarItem(
text: 'Services',
onPressed: ()
Get.to(AboutPage());
,
),
NavBarItem(
text: 'FAQ',
onPressed: ()
Get.to(AboutPage());
,
),
];
class NavBarItem extends StatefulWidget
final String text;
final Function onPressed;
NavBarItem(
required this.text,
required this.onPressed,
);
@override
_NavBarItemState createState() => _NavBarItemState();
class _NavBarItemState extends State<NavBarItem>
Color color = notSelected;
@override
Widget build(BuildContext context)
return MouseRegion(
onEnter: (value)
setState(()
color = selected;
);
,
onExit: (value)
setState(()
color = notSelected;
);
,
child: Material(
color: Colors.transparent,
child: InkWell(
splashColor: Colors.white60,
onTap: () ,
child: Container(
height: 60.0,
alignment: Alignment.centerLeft,
margin: EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
widget.text,
style: TextStyle(
fontSize: 16.0,
color: color,
),
),
),
),
),
);
class NavBarButton extends StatefulWidget
final Function onPressed;
NavBarButton(
required this.onPressed,
);
@override
_NavBarButtonState createState() => _NavBarButtonState();
class _NavBarButtonState extends State<NavBarButton>
Widget build(BuildContext context)
return Container(
height: 55.0,
width: 60.0,
decoration: BoxDecoration(
border: Border.all(
color: Color(0xcfffffff),
width: 2.0,
),
borderRadius: BorderRadius.circular(15.0),
),
child: Material(
color: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: InkWell(
splashColor: Colors.white60,
onTap: ()
setState(()
widget.onPressed();
);
,
child: Icon(
Icons.menu,
size: 30.0,
color: Color(0xcfffffff),
),
),
),
);
我们将不胜感激任何帮助
【问题讨论】:
请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。 【参考方案1】:您好 Asver Seb,您使用了错误的方法。我最近在 Flutter Web 上完成了一项工作,这里使用我的导航栏/标题代码来构建您正在寻找的内容,它会做得非常好。
class Header extends StatelessWidget
const Header(
Key? key,
) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
margin: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
child: Row(
children: <Widget>[
Image.asset(
'assets/images/logo.png',
width: 50,
),
SizedBox(width: 10),
Shimmer.fromColors(
baseColor: Colors.transparent,
highlightColor: Colors.amber,
child: Text(
"Webster",
style: TextStyle(fontSize: 32, fontWeight: FontWeight.w800),
)),
Spacer(),
NavItem(
title: 'Home',
tapEvent: ()
Get.to(HomeScreen());
,
),
NavItem(
title: 'About',
tapEvent: ()
Get.to(About());
,
),
NavItem(
title: 'FAQ',
tapEvent: ()
Get.to(Faq());
,
),
],
),
);
class NavItem extends StatelessWidget
const NavItem(Key? key, required this.title, required this.tapEvent)
: super(key: key);
final String title;
final GestureTapCallback tapEvent;
@override
Widget build(BuildContext context)
return InkWell(
onTap: tapEvent,
hoverColor: Colors.transparent,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: Text(
title,
style: TextStyle(fontWeight: FontWeight.w300),
),
),
);
【讨论】:
效果很好,非常感谢以上是关于如何在 List 小部件 Flutter 中无上下文导航的主要内容,如果未能解决你的问题,请参考以下文章
Flutter小部件测试中如何使用List的find.byType匹配
如何在 Flutter 的同一屏幕上沿 ListView 显示小部件?