Home > Net >  Pass event from one widget to another flutter (bottom nav bar tap)
Pass event from one widget to another flutter (bottom nav bar tap)

Time:05-19

I have a BottomNavBar widget which I navigate to from the app. Then the selected index determines which screen is visible in the body.

My question is, how can I tell the HomeScreen() widget that a user has tapped the home button in the nav bar so I can scroll to the top on that widget.

class BottomNavBar extends StatefulWidget { final int index;

  const BottomNavBar({Key key, this.index = 0}) : super(key: key);

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

class _BottomNavBarState extends State<BottomNavBar> {
  int _selectedIndex;

  @override
  void initState() {
    super.initState();
    _selectedIndex = widget.index;
  }

  // Screens
  final List<Widget> _screens = [
    const HomeScreen(),
    const DiscoverScreen(),
    const ProjectsScreen(),
    const ChatsScreen(),
    const ProfileScreen(),
  ];

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
      body: _screens[_selectedIndex],
      bottomNavigationBar: Container(
        decoration: const BoxDecoration(
          color: Colors.white,
          border: Border(
            top: BorderSide(
              color: Colors.black38,
              width: 0.2,
            ),
          ),
        ),
        child: BottomNavigationBar(
          currentIndex: _selectedIndex,
          type: BottomNavigationBarType.fixed,
          showSelectedLabels: false,
          showUnselectedLabels: false,
          selectedIconTheme: const IconThemeData(
            color: kMainColor,
          ),
          unselectedIconTheme: const IconThemeData(
            color: Color.fromRGBO(202, 205, 219, 1),
          ),
          onTap: (index) {
            // TODO If the current screen is home page and we tap the home button
            if (_selectedIndex == 0 && index == 0) {

            }
            setState(() {
              _selectedIndex = index;
            });
          },
          items: const [
            BottomNavigationBarItem(
              label: "",
              icon: Icon(
                FlutterIcons.home_fea,
              ),
            ),
          ],
        ),
      ),
    );
  }

CodePudding user response:

Just pass ScrollController to HomeScreen()

Example code:

main.dart

import 'package:demo/home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;
  final PageController _controller = PageController();
  final ScrollController _scrollController = ScrollController();

  @override
  void dispose() {
    _scrollController.dispose(); // dispose the controller
    super.dispose();
  }

  void _scrollToTop() {
    _scrollController.animateTo(0,
        duration: const Duration(seconds: 1), curve: Curves.linear);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: PageView(
          controller: _controller,
          children: [
            HomeScreen(
              controller: _scrollController,
            ),
            Container(
              color: Colors.blueGrey,
            ),
          ],
        ),
        bottomNavigationBar: Container(
          decoration: const BoxDecoration(
            color: Colors.white,
            border: Border(
              top: BorderSide(
                color: Colors.black38,
                width: 0.2,
              ),
            ),
          ),
          child: BottomNavigationBar(
            currentIndex: _selectedIndex,
            type: BottomNavigationBarType.fixed,
            showSelectedLabels: false,
            showUnselectedLabels: false,
            unselectedIconTheme: const IconThemeData(
              color: Color.fromRGBO(202, 205, 219, 1),
            ),
            onTap: (index) {
              if (_selectedIndex == 0 && index == 0) {
                _scrollToTop();
              } else {
                _controller.jumpToPage(index);
              }
              setState(() {
                _selectedIndex = index;
              });

            },
            items: const [
              BottomNavigationBarItem(
                label: "",
                icon: Icon(
                  CupertinoIcons.add,
                ),
              ),
              BottomNavigationBarItem(
                label: "",
                icon: Icon(
                  CupertinoIcons.book,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

home.dart

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  final ScrollController controller;
  HomeScreen({Key? key, required this.controller}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      child: ListView(
        controller: widget.controller,
        children: [
          Container(
            height: 400,
            color: Colors.red,
          ),
          Container(
            height: 400,
            color: Colors.green,
          ),
          Container(
            height: 400,
            color: Colors.yellow,
          ),
          Container(
            height: 400,
            color: Colors.red,
          ),
        ],
      ),
    );
  }
}

I hope it helpfull for you!

  • Related