You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发:为BottomNavigationBar中的相机图标添加弹出菜单按钮

Solution: Add Popup Menu for Camera Icon in BottomNavigationBar

Hey there! To make the camera icon in your BottomNavigationBar show a popup menu instead of directly navigating to the Upload page, we'll modify the onTap handler and add a modal bottom sheet for the options. Here's the complete modified code with explanations:

Modified Code

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttershare/services/auth.dart';
import 'package:fluttershare/pages/activity_feed.dart';
import 'package:fluttershare/pages/profile.dart';
import 'package:fluttershare/pages/search.dart';
import 'package:fluttershare/pages/timeline.dart';
import 'package:fluttershare/pages/upload.dart';

// Placeholder pages for your upload options - replace these with your actual screen components
class UploadPost extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text('Upload Post')));
  }
}

class UploadReel extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text('Upload Reel')));
  }
}

class UploadStory extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title: Text('Upload Story')));
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final key = GlobalKey<State<BottomNavigationBar>>();
  AuthBase authBase = AuthBase();
  bool isAuth = false;
  PageController pageController;
  int pageIndex = 0;

  @override
  void initState() {
    super.initState();
    pageController = PageController();
  }

  @override
  void dispose() {
    pageController.dispose();
    super.dispose();
  }

  onPageChanged(int pageIndex) {
    setState(() {
      this.pageIndex = pageIndex;
    });
  }

  void onTap(int pageIndex) {
    // Check if the tapped item is the camera icon (index 2)
    if (pageIndex == 2) {
      _showUploadOptions(context);
    } else {
      // Normal navigation for other bottom bar items
      pageController.animateToPage(
        pageIndex,
        duration: Duration(milliseconds: 200),
        curve: Curves.easeInOut,
      );
    }
  }

  // Show bottom sheet with upload options
  void _showUploadOptions(BuildContext context) {
    showModalBottomSheet(
      context: context,
      // Add rounded corners for better UI
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
      ),
      builder: (context) {
        return Container(
          padding: EdgeInsets.symmetric(vertical: 16.0),
          child: Column(
            // Make sheet height fit content
            mainAxisSize: MainAxisSize.min,
            children: [
              ListTile(
                leading: Icon(Icons.photo_library, color: Theme.of(context).primaryColor),
                title: Text('Upload Post'),
                onTap: () {
                  Navigator.pop(context); // Close the sheet first
                  Navigator.push(context, MaterialPageRoute(builder: (context) => UploadPost()));
                },
              ),
              ListTile(
                leading: Icon(Icons.video_camera_front, color: Theme.of(context).primaryColor),
                title: Text('Upload Reel'),
                onTap: () {
                  Navigator.pop(context);
                  Navigator.push(context, MaterialPageRoute(builder: (context) => UploadReel()));
                },
              ),
              ListTile(
                leading: Icon(Icons.story, color: Theme.of(context).primaryColor),
                title: Text('Upload Story'),
                onTap: () {
                  Navigator.pop(context);
                  Navigator.push(context, MaterialPageRoute(builder: (context) => UploadStory()));
                },
              ),
            ],
          ),
        );
      },
    );
  }

  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: PageView(
        children: <Widget>[
          Timeline(),
          ActivityFeed(),
          Upload(), // This page is no longer accessible via bottom nav - remove if not needed
          Search(),
          Profile(),
        ],
        controller: pageController,
        onPageChanged: onPageChanged,
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
        currentIndex: pageIndex,
        onTap: onTap,
        activeColor: Theme.of(context).primaryColor,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.whatshot)),
          BottomNavigationBarItem(icon: Icon(Icons.notifications_active)),
          BottomNavigationBarItem(
            icon: Icon(
              Icons.photo_camera,
              size: 35.0,
            ),
          ),
          BottomNavigationBarItem(icon: Icon(Icons.search)),
          BottomNavigationBarItem(icon: Icon(Icons.account_circle)),
        ],
      ),
    );
  }
}

Key Changes Explained:

  1. Updated onTap Handler: We added a check for the camera icon (index 2). When tapped, it launches the popup menu instead of navigating directly.
  2. Added _showUploadOptions Function: This creates a modal bottom sheet with three interactive list tiles. Each tile closes the sheet and navigates to its corresponding upload page.
  3. Placeholder Pages: Simple placeholder screens are included for demonstration—swap these out with your actual upload-related components.
  4. UI Polish: Rounded corners on the bottom sheet and themed icons match your app's primary color for a cohesive look.

Now when users tap the camera icon, they'll see a clean popup menu with your three upload options, each leading to the correct screen!

内容的提问来源于stack exchange,提问作者noura 121

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:12:46