简体   繁体   English

如何在列表小部件 Flutter 中无上下文地导航

[英]How to navigate without context in List widget Flutter

I am developing a flutter web app in which I have developed custom navbar but I am struggling to add navigation in the navbar items.我正在开发一个 Flutter Web 应用程序,我在其中开发了自定义导航栏,但我正在努力在导航栏项目中添加导航。 I've tried Get to navigate without context but unfortunately it isn't working on the list I've created.我试过 Get 在没有上下文的情况下导航,但不幸的是它不适用于我创建的列表。 I did tried to create function and put navigation as required for it but still no luck.我确实尝试创建函数并根据需要放置导航,但仍然没有运气。

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

Any help will be highly appreciated任何帮助将不胜感激

There's a another way to navigate without a context by using a global key for your navigation.还有另一种在没有上下文的情况下导航的方法,即使用全局键进行导航。 Firstly you will install get_it package for service location and create a class for it, then add navigatorKey property of your Materialapp.首先,您将为服务位置安装 get_it 包并为其创建一个类,然后添加 Materialapp 的 navigatorKey 属性。 Then you make an instance of the navigation service at the class you want, Finally you can navigate or use your custom dialog without context.然后你在你想要的类中创建一个导航服务的实例,最后你可以在没有上下文的情况下导航或使用你的自定义对话框。 For more details check this answer:有关更多详细信息,请查看此答案:

https://stackoverflow.com/a/69412029/15238208 https://stackoverflow.com/a/69412029/15238208

Hi Asver Seb you are following wrong method.嗨,Asver Seb,您遵循错误的方法。 I've recently done a job on flutter web here use my code of navbar/header to build what you are looking for it will do perfectly fine.我最近在 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),
        ),
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM