首页 > 解决方案 > 将需要参数的函数传递给flutter中的子小部件

问题描述

我正在寻找一种animated bottom navigation bar无需点击底部菜单即可更改活动选项卡的方法。需要一种创建Back按钮的方法和一种在提交表单后自动更改选项卡的方法。

我找不到如何做到这一点的完整示例。将来可能会帮助某人。

标签: flutterdart

解决方案


在你的父 Widget 中定义你的函数,就像你通常做的那样:

void selectedTab(index) {
    if (_bottomNavIndex != index) {
      setState(() {
        _bottomNavIndex = index;
      });
    }
  }

然后将此函数作为参数传递给您的Child小部件:

  Page5(
    selectedTab: selectedTab, // Notice it's not selectedTab()
  )

在您的Child小部件中定义预期的功能:

 const Page5({Key? key,required this.selectedTab}) : super(key: key);
    
  //? Use type ValueSetter if passing a argument
  //? Use type ValueGtetter if you are not passing an argument but expecting a value to be returned
  //? Use type VoidCallback if not sending or receiving a value
  final ValueSetter<int> selectedTab;

您使用传递给您的Child小部件的任何数据/函数的方式是使用widget 您可以widget.functionName(argument)在此示例中使用调用此函数widget.selectedTab(index)

完整代码如下:

import 'package:flutter/material.dart';
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
//! Import pages/tabs ...


// Home.dart
class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

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

class _HomeState extends State<Home> {
  int _bottomNavIndex = 4;

  void selectedTab(index) {
    if (_bottomNavIndex != index) {
      setState(() {
        _bottomNavIndex = index;
      });
    }
  }


    Widget getBody() {
    List<Widget> pages = [
      const Page0(),
      const Page1(),
      const Page2(),
      // ...
      Page5(
        selectedTab: selectedTab,
      )
    ];
    return IndexedStack(
      index: _bottomNavIndex,
      children: pages,
    );
  }

    Widget getFooter() {
    List<IconData> iconItems = [
      Icons.calendar_today_outlined,
      Icons.stacked_bar_chart_outlined,
      Icons.account_balance_outlined,
      Icons.settings
      Icons.access_alarm,
      Icons.umbrella_outlined,
    ];

    return AnimatedBottomNavigationBar(
      activeColor: Colors.deepPurple,
      splashColor: Colors.greenAccent,
      inactiveColor: Colors.black.withOpacity(0.5),
      icons: iconItems,
      activeIndex: _bottomNavIndex,
      gapLocation: GapLocation.center,
      notchSmoothness: NotchSmoothness.softEdge,
      leftCornerRadius: 10,
      iconSize: 25,
      rightCornerRadius: 10,
      onTap: (index) {
        selectedTab(index);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: getBody(),
      floatingActionButton: InkWell(
        splashColor: Colors.greenAccent,
        onLongPress: () {
          selectedTab(4);
        },
        child: FloatingActionButton(
          backgroundColor: Colors.deepPurple,
          elevation: 1,
          child: const Icon(Icons.add),
          onPressed: () {
            selectedTab(5);
          },
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: getFooter(),
    );
  }
}


// Page5.dart
class Page5 extends StatefulWidget {
 const Page5({Key? key,required this.selectedTab}) : super(key: key);
  
  
  //? Use type ValueSetter if passing a argument
  //? Use type ValueGtetter if you are not passing an argument but expecting a value to be returned
  //? Use type VoidCallback if not sending or receiving a value
  final ValueSetter<int> selectedTab;

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

class _Page5State extends State<Page5> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
          onPressed: () {
            widget.selectedTab(0);
          },
          child: Text('Go Home')),
    );
  }
}

推荐阅读