我想制作一个带有 3 个图标的底部导航栏,中间的图标充当浮动操作按钮,但看起来像普通的导航图标

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

我是一名新开发人员,我很难弄清楚这一点。

就像标题所说,我想创建一个导航栏,它有三个图标,但有两个页面连接到左右图标,中间图标有一个 CupertinoFullscreenDialogTransition,它直接打开一个上传图像的对话框。

我能够完成大部分工作,但在两个页面之间没有一个空白的中间页,用户在页面之间滑动时会看到该中间页。这就是我现在的位置:

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

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

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

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

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _currentIndex = 0;
  final PageController _pageController = PageController(
    initialPage: 0,
  );

  void _onTabTapped(int index) {
    if (index == 0 || index == 2) {
      setState(() {
        _currentIndex = index;
        _pageController.animateToPage(
          index,
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeInOut,
        );
      });
    } else {
      Navigator.of(context).push(
        PageRouteBuilder(
          opaque: false,
          pageBuilder: (context, _, __) {
            return const FullDialogPage();
          },
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        // padEnds: ,
        controller: _pageController,
        onPageChanged: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
        children: const [
          TimelineScreen(),
          Scaffold(
            // appBar: AppBar(
            //   title: const Text(''),
            // ),
            body: Center(
              child: Text(''),
            ),
          ),
          ProfileScreen(),
        ],
      ),
      bottomNavigationBar: CupertinoTabBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.home),
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.search),
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.person),
          ),
        ],
        currentIndex: _currentIndex,
        onTap: _onTabTapped,
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Timeline'),
      ),
      backgroundColor: Colors.white,
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          Center(
            child: Text('Timeline Screen'),
          ),
        ],
      ),
    );
  }
}

//pop up Page
class FullDialogPage extends StatefulWidget {
  const FullDialogPage({super.key});

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

class FullDialogPageState extends State<FullDialogPage>
    with TickerProviderStateMixin {
  late AnimationController _primary, _secondary;
  late Animation<double> _animationPrimary, _animationSecondary;

  @override
  void initState() {
    //Primaty
    _primary = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 600));
    _animationPrimary = Tween<double>(begin: 0, end: 1)
        .animate(CurvedAnimation(parent: _primary, curve: Curves.easeInOut));
    //Secondary
    _secondary = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 600));
    _animationSecondary = Tween<double>(begin: 0, end: 1)
        .animate(CurvedAnimation(parent: _secondary, curve: Curves.easeInOut));
    _primary.forward();
    super.initState();
  }

  @override
  void dispose() {
    _primary.dispose();
    _secondary.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoFullscreenDialogTransition(
      primaryRouteAnimation: _animationPrimary,
      secondaryRouteAnimation: _animationSecondary,
      linearTransition: false,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.indigo[900],
          title: const Text("Upload an image"),
          leading: IconButton(
            icon: const Icon(Icons.arrow_back),
            onPressed: () {
              _primary.reverse();
              Future.delayed(const Duration(milliseconds: 600), () {
                Navigator.of(context).pop();
              });
            },
          ),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile'),
      ),
      backgroundColor: Colors.white,
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          Center(
            child: Text('Profile Screen'),
          ),
        ],
      ),
    );
  }
}

flutter flutter-animation flutter-navigation
1个回答
0
投票

如果您检查

children
,它实际上显示的是当前的[白屏]。

children: const [
  TimelineScreen(),
  Scaffold(
    body: Center(
      child: Text(''),
    ),
  ),

您需要提供正确的孩子。

children: const [
  TimelineScreen(),
  FullDialogPage(),
  ProfileScreen(),
],

我传递一个bool来控制动画,你可以使用其他方法,如routeArgumets。

class FullDialogPage extends StatefulWidget {
  const FullDialogPage({
    super.key,
    this.showAnimation = true,
  });

/// on initState
_animationPrimary = Tween<double>(begin:widget.showAnimation?0: 1, end: 1);
  if(widget.showAnimation) _primary.forward();

并更新页面

children: const [
  TimelineScreen(),
  FullDialogPage(showAnimation: false),
  ProfileScreen(),
],
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.