Flutter状态,根据底部导航栏item的索引更新内容

问题描述 投票:0回答:1

我正在构建一个 flutter 应用程序,在某些时候,我必须添加一个底部工作表,所以我使用了“showModalBottomSheet”。我还想在其中显示一个导航栏,所以我添加了一个“BottomNavigationBar”的自定义小部件,现在我想根据底部导航栏的项目索引显示一些内容,如果 index = 1 显示a

Text("Home")
if index = 2 显示
ListView.builder()
这是我的 2 个小部件:

身体小部件

class BuildBody extends StatefulWidget {
  final UserOfGift user;
  final UserOfGift friend;
  const BuildBody({
    super.key,
    required this.user,
    required this.friend,
  });

  @override
  State<BuildBody> createState() => _BuildBodyState();
}

class _BuildBodyState extends State<BuildBody> {
  final DatabaseService _databaseService = DatabaseService();
  bool isShown = true;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    Future displayBottomSheet() {
      return showModalBottomSheet(
          context: context,
          backgroundColor: Pallete.pinkyPink,
          showDragHandle: true,
          shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.vertical(top: Radius.circular(35))),
          builder: (_) => Container(
                constraints: const BoxConstraints(maxHeight: 450),
                height: 350,
                padding: const EdgeInsets.all(10),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Expanded(
                        child: ListView.builder(
                      itemCount: widget.user.friendList.length,
                      itemBuilder: (context, index) {
                        String friendUid = widget.user.friendList[index];
                        return StreamBuilder(
                          stream: _databaseService.getUserDataStream(friendUid),
                          builder: (context, snapshot) {
                            if (snapshot.hasData) {
                              UserOfGift friendFromList = snapshot.data!;
                              return FriendListTile(user: friendFromList);
                            }
                            return const SizedBox();
                          },
                        );
                      },
                    )),
                    Align(
                      alignment: Alignment.bottomCenter,
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: BuildBottomNavBar(
                          myUser: widget.user,
                        ),
                      ),
                    )
                  ],
                ),
              ));
    }

    return Center(
      child: SizedBox(
        height: screenSize.height,
        width: screenSize.width,
        child: GestureDetector(
          onHorizontalDragEnd: (details) {
            setState(() {
              if (details.primaryVelocity! > 0) {
                isShown = false;
              } else if (details.primaryVelocity! < 0) {
                isShown = true;
              }
            });
          },
          onVerticalDragEnd: (details) {
            setState(() {
              displayBottomSheet();
              print("update with display");
            });
          },
     ...// the rest of my code

底部导航栏

class BuildBottomNavBar extends StatefulWidget {
  final UserOfGift myUser;
  const BuildBottomNavBar({
    super.key,
    required this.myUser,
  });

  @override
  State<BuildBottomNavBar> createState() => _BuildBottomNavBarState();
}

class _BuildBottomNavBarState extends State<BuildBottomNavBar> {
  int _currentIndex = 0;
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    print("BuildBottomNavState widget rebuilt");
    return ClipRRect(
      borderRadius: BorderRadius.circular(15),
      child: SizedBox(
        height: 60,
        child: BottomNavigationBar(
          selectedItemColor: Pallete.boldPink,
          unselectedItemColor: Pallete.pinkyPink,
          elevation: 10,
          iconSize: 30,
          currentIndex: _currentIndex,
          onTap: (value) {
            setState(() {
              _currentIndex = value;
              if (_currentIndex == 2) {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => QRCodePage(user: widget.myUser),
                    ));
              }
            });
          },
          backgroundColor: Pallete.lightPink,
          items: const [
            BottomNavigationBarItem(
                icon: Icon(Icons.home_rounded), label: "Home"),
            BottomNavigationBarItem(
                icon: Icon(Icons.people_outline_rounded), label: "Friends"),
            BottomNavigationBarItem(
                icon: Icon(Icons.qr_code_rounded), label: "QR Code"),
          ],
        ),
      ),
    );
  }
}

我期望当用户点击底部导航栏上的“Friends”项目时立即显示

ListView.builder
或当他点击“Home”项目时显示
Text("Home")

我尝试使用一个函数来检查索引,然后将一些布尔值分配给 true 或 false,并根据该值显示我想要的小部件,但我遇到了一个问题,我需要点击底部导航之外的内容当我点击该项目以显示小部件后,它不会立即显示,而是我需要点击屏幕上的其他位置。

谢谢大家提前的帮助

flutter state bottom-sheet flutter-state bottom-navigation-bar
1个回答
0
投票

检查此示例并自行定制。

TestView
 中称之为 
MaterialApp:home

class TestView extends StatelessWidget {
  const TestView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test page"),
      ),
      body: Center(
        child: ElevatedButton(
          child: const Text('showModalBottomSheet'),
          onPressed: () {
            showModalBottomSheet<void>(
              //isScrollControlled: true, //If you want the model to be full height
              context: context,
              builder: (BuildContext context) {
                return const NavigationExample();
              },
            );
          },
        ),
      ),
    );
  }
}

这是带有

NavigationExample
ListView.builder
小部件。

class NavigationExample extends StatefulWidget {
  const NavigationExample({super.key});

  @override
  State<NavigationExample> createState() => _NavigationExampleState();
}

class _NavigationExampleState extends State<NavigationExample> {
  int currentPageIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: NavigationBar(
        onDestinationSelected: (int index) {
          setState(() {
            currentPageIndex = index;
          });
        },
        indicatorColor: Colors.amber[800],
        selectedIndex: currentPageIndex,
        destinations: const <Widget>[
          NavigationDestination(
            selectedIcon: Icon(Icons.home),
            icon: Icon(Icons.home_outlined),
            label: 'Home',
          ),
          NavigationDestination(
            icon: Icon(Icons.business),
            label: 'Business',
          ),
          NavigationDestination(
            selectedIcon: Icon(Icons.school),
            icon: Icon(Icons.school_outlined),
            label: 'School',
          ),
        ],
      ),
      body: <Widget>[
        Container(
          color: Colors.red,
          alignment: Alignment.center,
          child: const Text('Page 1'),
        ),
        ListView.builder(
            itemCount: 5,
            itemBuilder: (context, i) {
              return ListTile(
                title: Text("Index $i Title"),
                subtitle: Text("Index $i Subtitle"),
              );
            }),
        Container(
          color: Colors.blue,
          alignment: Alignment.center,
          child: const Text('Page 3'),
        ),
      ][currentPageIndex],
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.