颤动中页面控制器的提供者状态管理 [英] Provider state management for PageController in Flutter

查看:12
本文介绍了颤动中页面控制器的提供者状态管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用PageController制作了一个网站来控制一些屏幕的滚动。我制作了一个带有屏幕名称的菜单部分,当用户按下其中任何一个名称时,用户将导航到相应的屏幕。

该应用程序运行正常。但我重构了菜单按钮,这样我就可以控制它的样式,并在未来添加动画。

但当我重构按钮时,我无法传递PageController索引或nextPage函数。

这就是我考虑使用提供程序包的原因。然而,我以前没有安装包,而且我的设置似乎很复杂。因为我应该将PageController状态传递给按钮,并且该按钮应该使用新数字发送nextPage函数。

如何实现此目标?

以下是我的代码:

按钮:

class NavigationButton extends StatefulWidget {

  const NavigationButton({
    Key key,
    this.title,
    // this.onPressed
  }) : super(key: key);

  final String title;
  // final VoidCallback onPressed;

  @override
  _NavigationButtonState createState() => _NavigationButtonState();
}

class _NavigationButtonState extends State<NavigationButton> {

  bool isHovering = false;

  @override
  Widget build(BuildContext context) {

    return InkWell(
      child: Container(
        decoration: BoxDecoration(
          border: isHovering == true
          ? Border(right: BorderSide(color: Colors.blueGrey, width: 10))
          : Border(right: BorderSide.none)
        ),
        child: Text(
          widget.title,
          style: TextStyle(
            color: Colors.white,
            fontSize: 25
          )
        )
      ),
      onHover: (value) {
        setState(() {
          isHovering = value;
        });
      },
      onTap: () {}
    );
  }
}

主布局:

class MainLayout extends StatefulWidget {
  @override
  _MainLayoutState createState() => _MainLayoutState();
}

class _MainLayoutState extends State<MainLayout> {

  int _index = 0;
  int selectedButton;
  bool isHovering = false;
  PageController pageController = PageController();

  final List<String> _sectionsName = [
    "Home",
    "About",
    "Services",
    "Portfolio",
    "Testimonials",
    "News",
    "Contact"
  ];


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      appBar: MediaQuery.of(context).size.width > 760
      ? null
      : AppBar(
        elevation: 0.0,
        backgroundColor: Colors.transparent
      ),
      drawer: MediaQuery.of(context).size.width < 760 ? DrawerWidget() : null,
      body: Stack(
        children: [
          // MediaQuery.of(context).size.width < 760 ? Container() : DrawerWidget(),
          Listener(
            onPointerSignal: (pointerSignal) {
              if (pointerSignal is PointerScrollEvent) {
                if (pointerSignal.scrollDelta.dy > 0) {
                  if(_index < _sectionsName.length) {
                    // int newIndex = _index + 1;
                    // pageController.jumpToPage(newIndex);
                    pageController.nextPage(
                      curve: Curves.easeIn, duration: Duration(milliseconds: 500)
                    );
                  }
                }
                else
                {
                  if(_index < _sectionsName.length) {
                    // int newIndex = _index - 1;
                    // pageController.jumpToPage(newIndex);
                    pageController.previousPage(
                      curve: Curves.easeIn, duration: Duration(milliseconds: 500)
                    );
                  }
                }
              }
            },
            child: PageView(
              controller: pageController,
              scrollDirection: Axis.vertical,
              physics: NeverScrollableScrollPhysics(),
              children: [
                HeroSection(),
                AboutSection(),
                ServicesSection(),
                PortfolioSection(),
                TestimonialsSection(),
                NewsSection(),
                ContactSection()
              ],
              onPageChanged: (index) {
                _index = index;
              }
            )
          ),
          MediaQuery.of(context).size.width < 760
          ? Container()
          : Align(
            alignment: Alignment.centerRight,
            child: Container(
              height: 205,
              width: 200,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  for (int index = 0; index < _sectionsName.length; index++)
                  NavigationButton(title: _sectionsName[index])
                ]
              )
            )
          )
        ]
      )
    );
  }
}

提前感谢...

编辑:

我关注了@EdwynZN的回答,它非常有帮助。但我必须将索引从MainLayout传递到NavigationButton,如下所示:

主布局: NavigationButton(标题:_sectionsName[索引],索引:索引)

导航按钮: 将此代码添加到构造函数:this.index。 并将其传递给类:最终的int索引;

最后:

onTap: () {
        controller.animateToPage(widget.index, curve: Curves.easeIn, duration: Duration(milliseconds: 500));
      }

我希望有一天这会对某人有所帮助…

推荐答案

使用提供程序可以将需要页面控制器的小部件包装为ChangeNotifierProvider.Value

ChangeNotifierProvider.value(
    value: pageController,
    Align(
        alignment: Alignment.centerRight,
        child: Container(
          height: 205,
          width: 200,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              for (int index = 0; index < _sectionsName.length; index++)
              NavigationButton(title: _sectionsName[index])
            ]
          )
        )
      ),
),

然后所有NavigationButton都可以作为继承的小部件访问pageController

class _NavigationButtonState extends State<NavigationButton> {

  bool isHovering = false;
  PageController controller;
  int index;

  @override
  void didChangeDependencies() {
    controller = Provider.of<PageController>(context); //you can read the pagecontroller here
    index = controller.page.round(); // will update when the page changes so you can do some logic with colors
    super.didChangeDependencies();
  } 

  @override
  Widget build(BuildContext context) {

    return InkWell(
      child: Container(
        decoration: BoxDecoration(
          border: isHovering == true
          ? Border(right: BorderSide(color: Colors.blueGrey, width: 10))
          : Border(right: BorderSide.none)
        ),
        child: Text(
          widget.title,
          style: TextStyle(
            color: Colors.white,
            fontSize: 25
          )
        )
      ),
      onHover: (value) {
        setState(() {
          isHovering = value;
        });
      },
      onTap: () {}
    );
  }
}

这篇关于颤动中页面控制器的提供者状态管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆