简体   繁体   中英

How do I pass an integer from a child widget to the parent widget?

I'm in the process of making a custom navigation bar for my project, and need to pass the current page # from the child navigation bar widget, to the main page. I can't seem to figure out the best method for transferring the int.

Custom navigation bar with int needed to be accessed:

import 'package:flutter/material.dart';
import 'package:my_app/theme.dart';

class CustomNavBar extends StatefulWidget {
  const CustomNavBar({Key? key}) : super(key: key);

  @override
  State<CustomNavBar> createState() => _CustomNavBarState();
}

class _CustomNavBarState extends State<CustomNavBar> {
  //Need to pass this int to parent
  int currentPage = 0;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.all(0),
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(24),
          topRight: Radius.circular(24),
        ),
      ),
      color: primaryColor,
      child: Row(
        children: <Widget>[
          Expanded(child: navBarItem(0, Icons.home)),
          Expanded(child: navBarItem(1, Icons.looks_one_rounded)),
          Expanded(child: navBarItem(2, Icons.looks_two_rounded)),
          Expanded(child: navBarItem(3, Icons.looks_3_rounded)),
        ],
      ),
    );
  }

  Widget navBarItem(
    int index,
    IconData icon,
  ) {
    return GestureDetector(
      onTap: () {
        setState(() {
          currentPage = index;
        });
      },
      child: Container(
        height: 80,
        width: MediaQuery.of(context).size.width / 4,
        decoration: const BoxDecoration(
          color: Colors.transparent,
        ),
        child: Icon(
          icon,
          color: index == currentPage ? Colors.white : primaryAccentColor,
        ),
      ),
    );
  }
}

Main.dart where int is needed to be accessed:

import 'package:flutter/material.dart';
import 'package:my_app/Pages/home_page.dart';
import 'package:my_app/Pages/profile_page.dart';
import 'package:my_app/Pages/testing_page.dart';
import 'package:my_app/Pages/testing_page2.dart';
import 'package:my_app/widgets/custom_navbar_widget.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: RootPage(),
    );
  }
}

class RootPage extends StatefulWidget {
  const RootPage({Key? key}) : super(key: key);

  @override
  State<RootPage> createState() => _RootPageState();
}

class _RootPageState extends State<RootPage> {
  //Replace this int with the one set from CustomNavBar
  int currentPage = 0;

  List<Widget> pages = [
    const HomePage(),
    const ProfilePage(),
    const TestingPage(),
    const TestingPage2(),
  ];
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      top: false,
      child: Scaffold(
        extendBody: true,
        body: pages[currentPage],
        bottomNavigationBar: CustomNavBar(),
      ),
    );
  }
}

You can use a ValueChange . Actually, this is a signature for callbacks that report that an underlying value has changed.

Look at the implementation :

typedef ValueChanged<T> = void Function(T value);

Also, you can use it in the child class like this :

import 'package:flutter/material.dart';
import 'package:my_app/theme.dart';

class CustomNavBar extends StatefulWidget {
  const CustomNavBar({Key? key, required this.onItemSelect}) : super(key: key);

  final ValueChanged<int> onItemSelect;

  @override
  State<CustomNavBar> createState() => _CustomNavBarState();
}

class _CustomNavBarState extends State<CustomNavBar> {
  //Need to pass this int to parent
  int currentPage = 0;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.all(0),
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(24),
          topRight: Radius.circular(24),
        ),
      ),
      color: primaryColor,
      child: Row(
        children: <Widget>[
          Expanded(child: navBarItem(0, Icons.home)),
          Expanded(child: navBarItem(1, Icons.looks_one_rounded)),
          Expanded(child: navBarItem(2, Icons.looks_two_rounded)),
          Expanded(child: navBarItem(3, Icons.looks_3_rounded)),
        ],
      ),
    );
  }

  Widget navBarItem(
    int index,
    IconData icon,
  ) {
    return GestureDetector(
      onTap: () {
        setState(() {
          widget.onItemSelect(currentPage);
          currentPage = index;
        });
      },
      child: Container(
        height: 80,
        width: MediaQuery.of(context).size.width / 4,
        decoration: const BoxDecoration(
          color: Colors.transparent,
        ),
        child: Icon(
          icon,
          color: index == currentPage ? Colors.white : primaryAccentColor,
        ),
      ),
    );
  }
}

And check for new changes in parent, like this :

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: RootPage(),
    );
  }
}

class RootPage extends StatefulWidget {
  const RootPage({Key? key}) : super(key: key);

  @override
  State<RootPage> createState() => _RootPageState();
}

class _RootPageState extends State<RootPage> {
  //Replace this int with the one set from CustomNavBar
  int currentPage = 0;

  List<Widget> pages = [
    const HomePage(),
    const ProfilePage(),
    const TestingPage(),
    const TestingPage2(),
  ];
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      top: false,
      child: Scaffold(
        extendBody: true,
        body: pages[currentPage],
        bottomNavigationBar: CustomNavBar(onItemSelect: (value) => print(value),),
      ),
    );
  }
}

For more detail, please check : https://api.flutter.dev/flutter/foundation/ValueChanged.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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