dynamic_tabs 1.0.2+2

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 44

Buy Me A Coffee Donate

dynamic_tabs #

A Flutter plugin for letting the user edit the bottom tabs like the Curpertino iTunes App.

Getting Started #

  • Set persistIndex to true for saving the index of the current tab to disk, everytime the app launches it will open the last tab opened
  • Tags must be set for each item and must be unique
  • There are 2 Modes DynamicTabScaffold.adaptive and DynamicTabScaffold. The latter just show material
  • When using adaptive mode the iOS Platform will be wrapped in a CupertinoTabBar and CurpertinoTabView, this means that the navigation can be perserved per tab and that the nav bar will be shown still on push. On Android it will push the whole screen
  • This widget allows you to use a stateless widget for navigation
  • This supports Dark Mode
  • If there are more than 5 Tabs there will be a 5th Tab Created Call "More" and it will show a list of the remaining tabs
  • On the edit screen the user can reorder that tabs to the nav bar as they wish, this will also be saved to disk
  • If Using .adaptive Cupertino Widgets are Required and YOu will have to provide the routes for the Navigator.
  • You can set the max number of tabs

Screenshots #

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

import 'package:dynamic_tabs/dynamic_tabs.dart';

import 'dart:io' show Platform;
import 'package:flutter/foundation.dart';

// The existing imports
// !! Keep your existing impots here !!

/// main is entry point of Flutter application
void main() {
  // Desktop platforms aren't a valid platform.
  _setTargetPlatformForDesktop();
  
  return runApp(MyApp());
}

/// If the current platform is desktop, override the default platform to
/// a supported platform (iOS for macOS, Android for Linux and Windows).
/// Otherwise, do nothing.
void _setTargetPlatformForDesktop() {
  TargetPlatform targetPlatform;
  if (Platform.isMacOS) {
    targetPlatform = TargetPlatform.iOS;
  } else if (Platform.isLinux || Platform.isWindows) {
    targetPlatform = TargetPlatform.android;
  }
  if (targetPlatform != null) {
    debugDefaultTargetPlatformOverride = targetPlatform;
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      home: new HomeScreen(),
      routes: _buildRoutes(context),
    );
  }
}

Map<String, WidgetBuilder> _buildRoutes(BuildContext context) =>
    <String, WidgetBuilder>{
      '/help': (BuildContext context) => RandomScreen(
            color: Colors.redAccent,
            title: "Info",
          ),
      '/about': (BuildContext context) => RandomScreen(
            color: Colors.amber,
            title: "Account",
          ),
    };

class HomeScreen extends StatefulWidget {
  const HomeScreen({
    Key key,
  }) : super(key: key);

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

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return DynamicTabScaffold.adaptive(
      routes: _buildRoutes(context),
      persistIndex: true,
      maxTabs: 4,
      tabs: <DynamicTab>[
        DynamicTab(
          child: RandomScreen(
            color: Colors.redAccent,
            title: "Info",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Info"),
            icon: Icon(Icons.info),
          ),
          tag: "info", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.amber,
            title: "Account",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Account"),
            icon: Icon(Icons.account_circle),
          ),
          tag: "account", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.blueGrey,
            title: "Help",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Help"),
            icon: Icon(Icons.help),
          ),
          tag: "help", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.purple,
            title: "Settings",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Settings"),
            icon: Icon(Icons.settings),
          ),
          tag: "settings", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.yellow,
            title: "Theme",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Theme"),
            icon: Icon(Icons.palette),
          ),
          tag: "theme", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.grey,
            title: "FAQ",
          ),
          tab: BottomNavigationBarItem(
            title: Text("FAQ"),
            icon: Icon(Icons.perm_contact_calendar),
          ),
          tag: "faq", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.pink,
            title: "Contacts",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Contacts"),
            icon: Icon(Icons.people),
          ),
          tag: "contacts", // Must Be Unique
        ),
      ],
    );
  }
}

class RandomScreen extends StatelessWidget {
  RandomScreen({
    @required this.title,
    @required this.color,
  });
  final String title;
  final Color color;
  @override
  Widget build(BuildContext context) {
    if (Platform.isIOS) {
      return CupertinoPageScaffold(
        child: CustomScrollView(
          slivers: <Widget>[
            CupertinoSliverNavigationBar(
              largeTitle: Text(title),
              previousPageTitle: "More",
            ),
            SliverToBoxAdapter(
              child: Container(
                color: color,
              ),
            ),
          ],
        ),
      );
    }
    return CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          title: Text(title),
        ),
        SliverFillRemaining(
          child: Container(
            color: color,
          ),
        ),
      ],
    );
  }
}


1.0.2 - 05.28.2019 #

  • Adding masterDetailOnMoreTab which will show a splitview for tablets in landscape
  • Updated Example

1.0.1 - 05.14.2019 #

  • Upgrading Dependencies

1.0.0 - 05.04.2019 #

  • Support for Dynamicly Generated Drawer on Desktop (Adaptive)
  • Updated Example
  • Fixing Bug in how data is stored on Desktop and Mobile
  • Requires Flutter master Channel or Dart sdk: ">=2.2.2 <3.0.0"

0.3.1 - 04.06.2019 #

  • Updating Example to be desktop aware

0.3.0 - 04.05.2019 #

  • Persisting Index on More Tab

0.2.0 #

  • Adding Material Options for .adaptive Scaffold

0.1.0 #

  • Adding Color Options for More Tab

0.0.8 #

  • Updating to Support More

0.0.7 #

  • Adding Optional Tag if using multi sets of dynamic_tabs

0.0.6 #

  • Removing Title Generator, now just uses child
  • Removing Dependency for Platform Widgets
  • Support for iOS 11 Large Titles

0.0.5 #

  • Adding Necessary Routes for Cupertino Tab View

0.0.4 #

  • Adding Feedback for When Drag will succeed

0.0.3 #

  • Added 'maxTabs' to limit hoe many tabs to show before the edit tab.
  • Thanks to "UnqleSquid" from Reddit

0.0.1 #

  • Fixed Landscape View
  • Adding Optional Title Widget

0.0.1 #

  • Created Plugin.

example/README.md

dynamic_tabs_example #

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

import 'package:dynamic_tabs/dynamic_tabs.dart';

import 'dart:io' show Platform;
import 'package:flutter/foundation.dart';

// The existing imports
// !! Keep your existing impots here !!

/// main is entry point of Flutter application
void main() {
  // Desktop platforms aren't a valid platform.
  _setTargetPlatformForDesktop();
  
  return runApp(MyApp());
}

/// If the current platform is desktop, override the default platform to
/// a supported platform (iOS for macOS, Android for Linux and Windows).
/// Otherwise, do nothing.
void _setTargetPlatformForDesktop() {
  TargetPlatform targetPlatform;
  if (Platform.isMacOS) {
    targetPlatform = TargetPlatform.iOS;
  } else if (Platform.isLinux || Platform.isWindows) {
    targetPlatform = TargetPlatform.android;
  }
  if (targetPlatform != null) {
    debugDefaultTargetPlatformOverride = targetPlatform;
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      home: new HomeScreen(),
      routes: _buildRoutes(context),
    );
  }
}

Map<String, WidgetBuilder> _buildRoutes(BuildContext context) =>
    <String, WidgetBuilder>{
      '/help': (BuildContext context) => RandomScreen(
            color: Colors.redAccent,
            title: "Info",
          ),
      '/about': (BuildContext context) => RandomScreen(
            color: Colors.amber,
            title: "Account",
          ),
    };

class HomeScreen extends StatefulWidget {
  const HomeScreen({
    Key key,
  }) : super(key: key);

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

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return DynamicTabScaffold.adaptive(
      routes: _buildRoutes(context),
      persistIndex: true,
      maxTabs: 4,
      tabs: <DynamicTab>[
        DynamicTab(
          child: RandomScreen(
            color: Colors.redAccent,
            title: "Info",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Info"),
            icon: Icon(Icons.info),
          ),
          tag: "info", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.amber,
            title: "Account",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Account"),
            icon: Icon(Icons.account_circle),
          ),
          tag: "account", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.blueGrey,
            title: "Help",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Help"),
            icon: Icon(Icons.help),
          ),
          tag: "help", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.purple,
            title: "Settings",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Settings"),
            icon: Icon(Icons.settings),
          ),
          tag: "settings", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.yellow,
            title: "Theme",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Theme"),
            icon: Icon(Icons.palette),
          ),
          tag: "theme", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.grey,
            title: "FAQ",
          ),
          tab: BottomNavigationBarItem(
            title: Text("FAQ"),
            icon: Icon(Icons.perm_contact_calendar),
          ),
          tag: "faq", // Must Be Unique
        ),
        DynamicTab(
          child: RandomScreen(
            color: Colors.pink,
            title: "Contacts",
          ),
          tab: BottomNavigationBarItem(
            title: Text("Contacts"),
            icon: Icon(Icons.people),
          ),
          tag: "contacts", // Must Be Unique
        ),
      ],
    );
  }
}

class RandomScreen extends StatelessWidget {
  RandomScreen({
    @required this.title,
    @required this.color,
  });
  final String title;
  final Color color;
  @override
  Widget build(BuildContext context) {
    if (Platform.isIOS) {
      return CupertinoPageScaffold(
        child: CustomScrollView(
          slivers: <Widget>[
            CupertinoSliverNavigationBar(
              largeTitle: Text(title),
              previousPageTitle: "More",
            ),
            SliverToBoxAdapter(
              child: Container(
                color: color,
              ),
            ),
          ],
        ),
      );
    }
    return CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          title: Text(title),
        ),
        SliverFillRemaining(
          child: Container(
            color: color,
          ),
        ),
      ],
    );
  }
}


Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dynamic_tabs: ^1.0.2+2

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:dynamic_tabs/dynamic_tabs.dart';
  
Version Uploaded Documentation Archive
1.0.2+2 May 29, 2019 Go to the documentation of dynamic_tabs 1.0.2+2 Download dynamic_tabs 1.0.2+2 archive
1.0.2+1 May 29, 2019 Go to the documentation of dynamic_tabs 1.0.2+1 Download dynamic_tabs 1.0.2+1 archive
1.0.2 May 28, 2019 Go to the documentation of dynamic_tabs 1.0.2 Download dynamic_tabs 1.0.2 archive
1.0.1+1 May 24, 2019 Go to the documentation of dynamic_tabs 1.0.1+1 Download dynamic_tabs 1.0.1+1 archive
1.0.1 May 14, 2019 Go to the documentation of dynamic_tabs 1.0.1 Download dynamic_tabs 1.0.1 archive
1.0.0 May 6, 2019 Go to the documentation of dynamic_tabs 1.0.0 Download dynamic_tabs 1.0.0 archive
0.4.0 Apr 6, 2019 Go to the documentation of dynamic_tabs 0.4.0 Download dynamic_tabs 0.4.0 archive
0.3.0 Apr 5, 2019 Go to the documentation of dynamic_tabs 0.3.0 Download dynamic_tabs 0.3.0 archive
0.2.0 Mar 28, 2019 Go to the documentation of dynamic_tabs 0.2.0 Download dynamic_tabs 0.2.0 archive
0.1.0+2 Mar 27, 2019 Go to the documentation of dynamic_tabs 0.1.0+2 Download dynamic_tabs 0.1.0+2 archive

All 26 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
60
Health:
Code health derived from static analysis. [more]
0
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
70
Overall:
Weighted score of the above. [more]
44
Learn more about scoring.

We analyzed this package on Jun 26, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.3.2
  • pana: 0.12.18
  • Flutter: 1.5.4-hotfix.2

Platforms

Detected platforms:

Error(s) prevent platform classification:

Fix dependencies in pubspec.yaml.

Analysis issues and suggestions

Fix dependencies in pubspec.yaml.

Running flutter pub upgrade failed with the following output:

ERR: The current Flutter SDK version is 1.5.4-hotfix.2.
 
 Because cupertino_controllers >=0.1.1 depends on flutter_sticky_header >=0.4.0 which requires Flutter SDK version >=1.5.9-pre.94 <2.0.0, cupertino_controllers >=0.1.1 is forbidden.
 So, because dynamic_tabs depends on cupertino_controllers ^0.1.1, version solving failed.

Maintenance issues and suggestions

Fix platform conflicts. (-20 points)

Error(s) prevent platform classification:

Fix dependencies in pubspec.yaml.

Make sure dartdoc successfully runs on your package's source files. (-10 points)

Dependencies were not resolved.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0