Bottom Tab Bar In Flutter

Bottom Tab Bar In Flutter :

Flutter tutorial provide this flutter application bottom tab bar (svg image), CachedNetworkImage, ListView horizontal, RichText and NestedScrollView.

Bottom Navigation provide icon underline.

Github link:https://github.com/JDKKamal/education_app

Screenshot :

Bottom Tab Bar In Flutter
Bottom Tab Bar In Flutter

Program : bottomNavigationBar.dart

import 'package:flutter/material.dart' as md;
import 'package:flutter_svg/flutter_svg.dart';

final md.Color defaultColor = md.Colors.grey[700];

final md.Color defaultOnSelectColor = md.Colors.grey;

class BottomNav extends md.StatefulWidget {
  final int index;
  final void Function(int i) onTap;
  final List<BottomNavItem> items;
  final double elevation;
  final IconStyle iconStyle;
  final md.Color color;
  final LabelStyle labelStyle;

  BottomNav({
    this.index,
    this.onTap,
    this.items,
    this.elevation = 0.0,
    this.iconStyle,
    this.color = md.Colors.white, //BACKGROUND COLOR
    this.labelStyle,
  })  : assert(items != null),
        assert(items.length >= 2);

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

class BottomNavState extends md.State<BottomNav> {
  int currentIndex;
  IconStyle iconStyle;
  LabelStyle labelStyle;

  @override
  void initState() {
    currentIndex = widget.index ?? 0;
    iconStyle = widget.iconStyle ?? IconStyle();
    labelStyle = widget.labelStyle ?? LabelStyle();
    super.initState();
  }

  @override
  md.Widget build(md.BuildContext context) {
    return md.Material(
        elevation: widget.elevation,
        color: widget.color,
        child: md.Row(
          mainAxisAlignment: md.MainAxisAlignment.spaceAround,
          mainAxisSize: md.MainAxisSize.max,
          children: widget.items.map((b) {
            final int i = widget.items.indexOf(b);
            final bool selected = i == currentIndex;

            return BMNavItem(
              icon: b.icon,
              iconSize:
                  selected ? iconStyle.getSelectedSize() : iconStyle.getSize(),
              label: parseLabel(b.label, labelStyle, selected),
              onTap: () => onItemClick(i),
              textStyle: selected
                  ? labelStyle.getOnSelectTextStyle()
                  : labelStyle.getTextStyle(),
              color: selected
                  ? iconStyle.getSelectedColor()
                  : iconStyle.getColor(),
            );
          }).toList(),
        ));
  }

  onItemClick(int i) {
    setState(() {
      currentIndex = i;
    });
    if (widget.onTap != null) widget.onTap(i);
  }

  parseLabel(String label, LabelStyle style, bool selected) {
    if (!style.isVisible()) {
      return null;
    }

    if (style.isShowOnSelect()) {
      return selected ? label : null;
    }

    return label;
  }
}

class BottomNavItem {
  final String icon;
  final String label;

  BottomNavItem(this.icon, {this.label});
}

class LabelStyle {
  final bool visible;
  final bool showOnSelect;
  final md.TextStyle textStyle;
  final md.TextStyle onSelectTextStyle;

  LabelStyle(
      {this.visible,
      this.showOnSelect,
      this.textStyle,
      this.onSelectTextStyle});

  isVisible() {
    return visible ?? true;
  }

  isShowOnSelect() {
    return showOnSelect ?? false;
  }

  // getTextStyle returns `textStyle` with default `fontSize` and
  // `color` values if not provided. if `textStyle` is null then
  // returns default text style
  getTextStyle() {
    if (textStyle != null) {
      return md.TextStyle(
        inherit: textStyle.inherit,
        color: textStyle.color ?? defaultOnSelectColor,
        fontSize: textStyle.fontSize ?? 12.0,
        fontWeight: textStyle.fontWeight,
        fontStyle: textStyle.fontStyle,
        letterSpacing: textStyle.letterSpacing,
        wordSpacing: textStyle.wordSpacing,
        textBaseline: textStyle.textBaseline,
        height: textStyle.height,
        locale: textStyle.locale,
        foreground: textStyle.foreground,
        background: textStyle.background,
        decoration: textStyle.decoration,
        decorationColor: textStyle.decorationColor,
        decorationStyle: textStyle.decorationStyle,
        debugLabel: textStyle.debugLabel,
        fontFamily: textStyle.fontFamily,
      );
    }
    return md.TextStyle(color: defaultColor, fontSize: 12.0);
  }

  // getOnSelectTextStyle returns `onSelectTextStyle` with
  // default `fontSize` and `color` values if not provided. if
  // `onSelectTextStyle` is null then returns default text style
  getOnSelectTextStyle() {
    if (onSelectTextStyle != null) {
      return md.TextStyle(
        inherit: onSelectTextStyle.inherit,
        color: onSelectTextStyle.color ?? defaultOnSelectColor,
        fontSize: onSelectTextStyle.fontSize ?? 12.0,
        fontWeight: onSelectTextStyle.fontWeight,
        fontStyle: onSelectTextStyle.fontStyle,
        letterSpacing: onSelectTextStyle.letterSpacing,
        wordSpacing: onSelectTextStyle.wordSpacing,
        textBaseline: onSelectTextStyle.textBaseline,
        height: onSelectTextStyle.height,
        locale: onSelectTextStyle.locale,
        foreground: onSelectTextStyle.foreground,
        background: onSelectTextStyle.background,
        decoration: onSelectTextStyle.decoration,
        decorationColor: onSelectTextStyle.decorationColor,
        decorationStyle: onSelectTextStyle.decorationStyle,
        debugLabel: onSelectTextStyle.debugLabel,
        fontFamily: onSelectTextStyle.fontFamily,
      );
    }
    return md.TextStyle(color: defaultOnSelectColor, fontSize: 12.0);
  }
}

class IconStyle {
  final double size;
  final double onSelectSize;
  final md.Color color;
  final md.Color onSelectColor;

  IconStyle({this.size, this.onSelectSize, this.color, this.onSelectColor});

  getSize() {
    return size ?? 24.0;
  }

  getSelectedSize() {
    return onSelectSize ?? 24.0;
  }

  getColor() {
    return color ?? defaultColor;
  }

  getSelectedColor() {
    return onSelectColor ?? defaultOnSelectColor;
  }
}

class BMNavItem extends md.StatelessWidget {
  final String icon;
  final double iconSize;
  final String label;
  final void Function() onTap;
  final md.Color color;
  final md.TextStyle textStyle;

  BMNavItem({
    this.icon,
    this.iconSize,
    this.label,
    this.onTap,
    this.color,
    this.textStyle,
  })  : assert(icon != null),
        assert(iconSize != null),
        assert(color != null),
        assert(onTap != null);

  @override
  md.Widget build(md.BuildContext context) {
    return md.Expanded(
        child: md.InkResponse(
      key: key,
      child: md.Padding(
          padding: getPadding(),
          child: md.Column(
              mainAxisSize: md.MainAxisSize.min,
              children: <md.Widget>[
                SvgPicture.asset(
                  icon,
                  height: iconSize,
                  color: color,
                  width: iconSize,
                ),
                md.SizedBox(
                  height: 5,
                ),

                //SET LINE BOTTOM IN IMAGE
                label != null
                    ? md.Container(
                        height: 1,
                        width: iconSize / 1.5,
                        color: color,
                      )
                    : md.Container(
                        height: 1, width: 10, color: md.Colors.transparent)
                // label != null
                //     ? md.Text(label, style: textStyle)
                //     : md.Container()
              ])),
      highlightColor: md.Theme.of(context).highlightColor,
      splashColor: md.Theme.of(context).splashColor,
      radius: md.Material.defaultSplashRadius,
      onTap: () => onTap(),
    ));
  }

  // getPadding returns the padding after adjusting the top and bottom
  // padding based on the fontsize and iconSize.
  getPadding() {
    if (label != null) {
      final double p = ((56 - textStyle.fontSize) - iconSize) / 2;
      return md.EdgeInsets.fromLTRB(0.0, p, 0.0, p);
    }
    return md.EdgeInsets.fromLTRB(
        0.0, (56 - iconSize) / 2, 0.0, (56 - iconSize) / 2);
  }
}

Program : Index.dart

import 'package:education_app/components/bottomNavigationBar.dart';
import 'package:education_app/screen/bottomTabs/homeTab.dart';
import 'package:education_app/screen/bottomTabs/placeholderTab.dart';
import 'package:flutter/material.dart';
import 'package:education_app/utils/Theme.dart' as AppTheme;

class Index extends StatefulWidget {
  @override
  _IndexState createState() => _IndexState();
}

class _IndexState extends State<Index> {
  int _selectedTab = 2;

  final _tabs = [
    PlaceholderTab(icon: "assets/images/bookmark.svg"),
    PlaceholderTab(icon: "assets/images/notification.svg"),
    HomeTab(),
    PlaceholderTab(icon: "assets/images/controls.svg"),
    PlaceholderTab(icon: "assets/images/user.svg"),
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: _tabs[_selectedTab],
        bottomNavigationBar: BottomNav(
          index: _selectedTab,
          labelStyle: LabelStyle(showOnSelect: true),
          iconStyle: IconStyle(onSelectColor: const Color(0xFFFF9233)),
          items: [
            BottomNavItem("assets/images/bookmark.svg", label: 'bookmark'),
            BottomNavItem("assets/images/notification.svg",
                label: 'notification'),
            BottomNavItem("assets/images/home.svg", label: 'home'),
            BottomNavItem("assets/images/controls.svg", label: 'Settings'),
            BottomNavItem("assets/images/user.svg", label: 'user')
          ],
          onTap: (index) {
            setState(() {
              _selectedTab = index;
            });
          },
        ));
  }
}

The flutter tutorial  is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application

For more information about Flutter. visit www.fluttertutorial.in