返回

仿闲鱼 Flutter BottomNavigationBar 效果精解

Android

仿闲鱼 BottomNavigationBar 实现解析

BottomNavigationBar 概述

BottomNavigationBar 组件是 Flutter 中用于在屏幕底部创建一个导航栏的控件。它可以包含多个 Item,每个 Item 代表一个导航选项。当单击一个 Item,则会触发一个回调,允许开发人员在单击该 Item 后进行特定的导航或交互。

仿制闲鱼 BottomNavigationBar 效果

闲鱼 App 的 BottomNavigationBar 具有独特的设计,与传统的 BottomNavigationBar 组件有细微差别。它的特点如下:

  • 背景色渐变: 导航栏的背景色从浅灰色渐变到深灰色。
  • Item 图标和文本垂直居中: Item 的图标和文本始终垂直居中,无论文本内容的长度。
  • Item 选中时的动画: 当选中一个 Item,该 Item 的图标会缩小,并用文本标签替换。
  • Item 未选中时的阴影: 未选中的 Item 具有轻微的阴影,营造出轻微的悬浮感。

实现仿制

1. 创建一个新 Flutter 项目

首先,使用你喜欢的 IDE 创建一个新 Flutter 项目。

2. 安装必要的库

要使用 BottomNavigationBar 组件,你需要导入 material 库:

import 'material.dart';

3. 定义 BottomNavigationBar

创建一个名为 MyBottomNavigationBar 的新类,它将扩展 StatefulWidget 类。

class MyBottomNavigationBar extends StatefulWidget {
  @override
  _MyBottomNavigationBarState createstate() => _MyBottomNavigationBarState();
}

class _MyBottomNavigationBarState extends State<MyBottomNavigationBar> {
  int _selectedIndex = 0;

  void _onItemTapped(int index) {
    setState() {
      _selectedIndex = index;
    }
  }

  @override
  Widget build( BuildContext context) {
    return BottomNavigationBar(
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Image.assent('images/home.png'),
          label: '主页'
        ),
        BottomNavigationBarItem(
          icon: Image.assent('images/order.png'),
          label: '订单'
        ),
        // 更多的 Item...
      ],
    )
  }
}

4. 设置背景色渐变

要为导航栏创建一个背景色渐变,请将 BottomNavigationBarbackground 属性设置为 GradientAppBar

class MyBottomNavigationBar extends StatefulWidget {
  @override
  _MyBottomNavigationBarState createstate() => _MyBottomNavigationBarState();
}

class _MyBottomNavigationBarState extends State<MyBottomNavigationBar> {
  int _selectedIndex = 0;

  // ... 省略已有的内容...

  @override
  Widget build( BuildContext context) {
    return BottomNavigationBar(
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
      items: const <BottomNavigationBarItem>[
        // ... 省略已有的内容...
      ],
      background:  GradientAppBar(
        gradient:  Gradient.linear(
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
          stops: [0, 1],
          color: [
            Color(0xffe2e2e2),
            Color(0xffa0a0a0),
          ],
        ),
      ),
    )
  }
}

5. 自定义 Item 布局

要使 Item 图标和文本垂直居中,你需要创建一个 BottomNavigationBarItem 的子类。

class MyBottomNavigationBarItem extends BottomNavigationBarItem {
  MyBottomNavigationBarItem(
      String label, Widget icon, { Key? key }
  ) : super(
      icon: icon,
      label: label,
      key: key
  );

  Widget _build() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        icon,
        const SizedBox( height: 8.0),
        Text(label),
      ]
    );
  }

  @override
  Widget build() {
    return MediaQuery.of(context).viwportWidth < 800
        ? _build() : BottomNavigationBarItem.build(this)
  }
}

使用新子类来替换 BottomNavigationBarItem 的现有定义:

class MyBottomNavigationBar extends StatefulWidget {
  // ... 省略已有的内容...

  @override
  Widget build( BuildContext context) {
    return BottomNavigationBar(
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
      items: const <BottomNavigationBarItem>[
        MyBottomNavigationBarItem(
          icon: Image.assent('images/home.png'),
          label: '主页'
        ),
        MyBottomNavigationBarItem(
          icon: Image.assent('images/order.png'),
          label: '订单'
        ),
        // 更多的 Item...
      ],
      background:  GradientAppBar(
        gradient:  Gradient.linear(
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
          stops: [0, 1],
          color: [
            Color(0xffe2e2e2),
            Color(0xffa0a0a0),
          ],
        ),
      ),
    )
  }
}

6. 添加 Item 选中动画

要为选中的 Item 添加缩小图标和替换文本标签的动画,可以使用 AnimatedSwitcher 组件。

class MyBottomNavigationBar extends StatefulWidget {
  // ... 省略已有的内容...

  @override
  Widget build( BuildContext context) {
    return BottomNavigationBar(
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
      items: const <BottomNavigationBarItem>[
        // ... 省略已有的内容...
      ],
      background:  GradientAppBar(
        gradient:  Gradient.linear(
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
          stops: [0, 1],
          color: [
            Color(0xffe2e2e2),
            Color(0xffa0a0a0),
          ],
        ),
      ),
    );
  }
}

7. 添加 Item 未选中阴影

要为未选中的 Item 添加轻微的阴影,可以使用 BoxShadow 组件。

class MyBottomNavigationBar extends StatefulWidget {
  // ... 省略已有的内容...

  @override
  Widget build( BuildContext context) {
    return BottomNavigationBar(
      currentIndex: _selectedIndex,
      onTap: _onItemTapped,
      items: const <BottomNavigationBarItem>[
        // ... 省略已有的内容...
      ],
      background:  GradientAppBar(
        gradient:  Gradient.linear(
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
          stops: [0, 1],
          color: [
            Color(0xffe2e2e2),
            Color(0xffa0a0a0),
          ],
        ),
      ),
    );
  }
}

8. 其他细节调整

你可以进一步调整导航栏以满足您的特定需求。例如,您可以调整 BottomNavigationBar 的高度、Item 间距、字体大小和颜色。

结论

仿制闲鱼 App 的 BottomNavigationBar 效果可以让你从头开始仿制复杂而独特的 UI 组件。这是一种有效的训练技巧,将帮助您提高 Flutter 开发技能。

本教程从头到尾逐步引导您完成了仿制闲鱼 BottomNavigationBar 的所有关键阶段。您可以使用此仿制方法来仿制类似的其他组件,并从中激发灵感,创造自己独特和创