Отзыв о реализации BottomNavigationBar в Flutter

Вопрос или проблема

это мой нижний навигационный бар

я хочу, чтобы он выглядел так

док для iPhone имеет закругленные углы

Я работаю над приложением на Flutter и только что реализовал BottomNavigationBar с кастомным AppBar. Ниже приведен код для виджета HomePage:

import 'package:flutter/material.dart';
import 'dart:ui'; // Для ImageFilter.blur

import 'screens/profile.dart';
import 'home_screen.dart';
import 'book_appointment.dart';
import 'screens/history.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _bottomNavIndex = 0;

  final List<Widget> _pages = [
    HomeScreen(),
    AppointmentPage(),
    HistoryPage(),
  ];

  final List<IconData> _iconList = [
    Icons.home_filled,
    Icons.add_rounded,
    Icons.history,
  ];

  final List<String> _titleList = [
    'Главная',
    'Записи',
    'История',
  ];

  PreferredSizeWidget? _buildAppBar() {
    if (_bottomNavIndex == 0) {
      return PreferredSize(
        preferredSize: Size.fromHeight(60),
        child: AppBar(
          backgroundColor: Colors.transparent,
          flexibleSpace: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage('assets/appbar.png'),
                fit: BoxFit.cover,
              ),
            ),
          ),
          title: GestureDetector(
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => ProfilePage()),
              );
            },
            child: Row(
              children: [
                Padding(
                  padding: EdgeInsets.only(top: 10),
                  child: CircleAvatar(
                    backgroundImage: AssetImage('assets/pogisivenz.png'),
                    radius: 20,
                  ),
                ),
                SizedBox(width: 10),
                Text(
                  'Привет, Харалд Поги',
                  style: TextStyle(color: Color(0xFFE5D9F2)),
                ),
              ],
            ),
          ),
        ),
      );
    }
    return null;
  }

  Widget _buildBottomNavigationBar() {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white, // Цвет фона для дока
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(30), // Закругленные углы сверху
        ),
        boxShadow: [
          BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10),
        ],
      ),
      margin: const EdgeInsets.only(bottom: 20.0), // Поля для эффекта всплытия
      child: ClipRRect(
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(30), // Соответствует закругленным углам сверху
        ),
        child: BottomNavigationBar(
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(_iconList[0]),
              label: _titleList[0],
            ),
            BottomNavigationBarItem(
              icon: Icon(_iconList[1]),
              label: _titleList[1],
            ),
            BottomNavigationBarItem(
              icon: Icon(_iconList[2]),
              label: _titleList[2],
            ),
          ],
          currentIndex: _bottomNavIndex,
          selectedItemColor: const Color.fromARGB(255, 116, 23, 133),
          unselectedItemColor: Colors.black,
          onTap: (index) {
            setState(() {
              _bottomNavIndex = index;
            });
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent, // Делаем фон Scaffold прозрачным
      appBar: _buildAppBar(),
      body: Stack(
        children: [
          Positioned.fill(
            child: Image.asset(
              'assets/splash.png',
              fit: BoxFit.cover,
            ),
          ),
          Positioned.fill(
            child: AnimatedSwitcher(
              duration: Duration(milliseconds: 300),
              child: _pages[_bottomNavIndex],
            ),
          ),
        ],
      ),
      bottomNavigationBar: _buildBottomNavigationBar(),
    );
  }
}

я пытался изменить это сам много раз, но у меня не получается, пожалуйста, помогите

Ответ или решение

Конечно! Давайте улучшить вашу реализацию BottomNavigationBar в Flutter, чтобы он выглядел как нижняя панель на iPhone с закругленными углами. Мы сосредоточимся на создании кастомизированного внешнего вида для BottomNavigationBar, который будет соответствовать вашему примеру.

Шаги для улучшения BottomNavigationBar

  1. Убедитесь, что у вас установлены правильные зависимости. Для современных версий Flutter рекомендуется использовать Flutter 2.0 или выше.

  2. Измените реализацию BottomNavigationBar. Вместо использования стандартного виджета, вы можете создать свой собственный виджет с кастомным дизайном.

  3. Обновите код в вашем HomePage. Вот пример обновленного кода:

import 'package:flutter/material.dart';
import 'screens/profile.dart';
import 'home_screen.dart';
import 'book_appointment.dart';
import 'screens/history.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _bottomNavIndex = 0;

  final List<Widget> _pages = [
    HomeScreen(),
    AppointmentPage(),
    HistoryPage(),
  ];

  final List<IconData> _iconList = [
    Icons.home_filled,
    Icons.add_rounded,
    Icons.history,
  ];

  final List<String> _titleList = [
    'Home',
    'Appointments',
    'History',
  ];

  PreferredSizeWidget? _buildAppBar() {
    if (_bottomNavIndex == 0) {
      return PreferredSize(
        preferredSize: Size.fromHeight(60),
        child: AppBar(
          backgroundColor: Colors.transparent,
          flexibleSpace: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage('assets/appbar.png'),
                fit: BoxFit.cover,
              ),
            ),
          ),
          title: GestureDetector(
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => ProfilePage()),
              );
            },
            child: Row(
              children: [
                Padding(
                  padding: EdgeInsets.only(top: 10),
                  child: CircleAvatar(
                    backgroundImage: AssetImage('assets/pogisivenz.png'),
                    radius: 20,
                  ),
                ),
                SizedBox(width: 10),
                Text(
                  'Hi, Harold Pogi',
                  style: TextStyle(color: Color(0xFFE5D9F2)),
                ),
              ],
            ),
          ),
        ),
      );
    }
    return null;
  }

  Widget _buildBottomNavigationBar() {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
        boxShadow: [
          BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10),
        ],
      ),
      margin: const EdgeInsets.only(bottom: 20.0),
      child: ClipRRect(
        borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
        child: BottomNavigationBar(
          items: _iconList.asMap().entries.map((entry) {
            int idx = entry.key;
            return BottomNavigationBarItem(
              icon: Icon(entry.value),
              label: _titleList[idx],
            );
          }).toList(),
          currentIndex: _bottomNavIndex,
          selectedItemColor: Color.fromARGB(255, 116, 23, 133),
          unselectedItemColor: Colors.black,
          onTap: (index) {
            setState(() {
              _bottomNavIndex = index;
            });
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      appBar: _buildAppBar(),
      body: Stack(
        children: [
          Positioned.fill(
            child: Image.asset(
              'assets/splash.png',
              fit: BoxFit.cover,
            ),
          ),
          Positioned.fill(
            child: AnimatedSwitcher(
              duration: Duration(milliseconds: 300),
              child: _pages[_bottomNavIndex],
            ),
          ),
        ],
      ),
      bottomNavigationBar: _buildBottomNavigationBar(),
    );
  }
}

Объяснение изменений

  • ClipRRect: мы используем ClipRRect для достижения эффекта закругления углов. Убедитесь, что borderRadius совпадает с круглыми углами контейнера.
  • Кастомизация BottomNavigationBar: мы используем a Container для создания фона с закругленными углами и наложением теней.
  • Адаптивность: вместо жесткого кодирования значков и названий, теперь мы используем asMap для динамической генерации иконок и названий.

Заключение

С помощью этих изменений вы сможете создать подходящую нижнюю навигационную панель с закругленными углами, которая будет выглядеть гораздо более современно и привлекательно, по аналогии с нижней панелью на iPhone. Если будут вопросы или потребуется дополнительная помощь, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...