flui 0.8.0

English | 简体中文


FLUI

A widget kit for Google Flutter Demo apk

pub package CI Status Documentation GitHub stars GitHub forks GitHub license

Features #

  • A set of high-quality Flutter widgets out of the box
  • Comprehensive usage examples and documentation
  • Fine-grained non-stylized widgets for different types of applications
  • Supports Dark Mode and RTL

Compatibility #

FLUI has good compatibility on multiple clients, and the framework will be developed based on Flutter Stable Channel.

Currently supports v1.12.13+hotfix.5 and above.

Getting Started #

Setup #

dependencies:
  flui: 0.8.0

Then run flutter pub get to download the dependencies.

Usage #

After the dependency installation is completed, you can directly import the widget.

import 'package:flui/flui.dart';

// in somewhere
FLAppBarTitle(
    title: 'AppBar',
    subtitle: '(subtitle)',
    layout: FLAppBarTitleLayout.vertical,
    showLoading: true
)

Widgets #

Contributing #

Principles:

  • Branches that submit new widgets should be named 'feature-' + widget name. Fixing issues need to be prefixed with 'bugfix-'
  • The submitted widgets need to be general. If the widget is rare or not sure whether it needs to be added to FLUI, you can raise a issue which starts with [feature] for discussion
  • The API design of the new widget is as standard and readable as possible, following the naming and usage rules of Flutter's official widgets.
  • Please comment above properties and methods how to use it so that I can add to the documentation and examples.
  • Commit messages: prefix with feat | fix | docs | style | refactor | perf | test | workflow | ci | chore | types:.

License #

MIT License

Change Log #

0.8.0 #

  • Flutter version upgrade to v1.12.13 + hotfix.5
  • Support Dark Mode
  • Support RTL text direction
  • Widget test integration
  • New widget FLCountStepper
  • FLToast add custom content view
  • FLMarqueeLabel and FLNoticeBar Added delayed scrolling property delay

Breaking changes: #

  • prefix and suffix of FLNoticeBar have been changed to prefixBuilder and suffixBuilder so that you can get the BuildContext instance to build the widget.
  • All dart files under 'lib' are migrated to 'lib/src' for dartdevc

0.7.4 #

  • fix some doc issue.

0.7.3 #

  • FLNoticeBar fix null velocity issue.

0.7.2 #

  • FLCupertinoOperationSheet add custom header widget.

0.7.0 #

First version, include 15 categories:

example/lib/main.dart

import 'dart:io';

import 'package:example/util.dart';
import 'package:example/pages/about_page.dart';
import 'package:example/pages/action_sheet_page.dart';
import 'package:example/pages/avatar_page.dart';
import 'package:example/pages/badge_page.dart';
import 'package:example/pages/bubble_page.dart';
import 'package:example/pages/button_page.dart';
import 'package:example/pages/count_stepper_page.dart';
import 'package:example/pages/empty_page.dart';
import 'package:example/pages/hints_action_empty_page.dart';
import 'package:example/pages/hints_empty_page.dart';
import 'package:example/home_page.dart';
import 'package:example/pages/image_hints_empty_page.dart';
import 'package:example/pages/label_page.dart';
import 'package:example/pages/app_bar_page.dart';
import 'package:example/pages/loading_empty_page.dart';
import 'package:example/pages/notice_page.dart';
import 'package:example/pages/skeleton_page.dart';
import 'package:example/pages/toast_page.dart';
import 'package:flui/flui.dart';
import 'package:example/pages/input_page.dart';
import 'package:example/pages/static_list_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:logger/logger.dart';
import 'package:example/style/theme.dart';

void main() {
  runApp(MyApp());
  if (Platform.isAndroid) {
    SystemUiOverlayStyle systemUiOverlayStyle =
        SystemUiOverlayStyle(statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  }
  Util.initialize();
}

Logger logger = Logger();

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

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  FLToastDefaults _defaults = FLToastDefaults();
  bool _userModeLoaded = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    Util.eventBus.on().listen((event) {
      if (event == 'reset') {
        setState(() {
          _defaults = FLToastDefaults();
        });
      } else if (event == 'theme') {
        setState(() {});
      } else if (event == 'themeLoaded') {
        if (!_userModeLoaded) setState(() {});
      } else if (event == 'direction') {
        setState(() {});
      } else {
        setState(() => _defaults = event);
      }
    });
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangePlatformBrightness() {
    if (Util.themeMode == ThemeMode.system) {
      setState(() {});
    }
  }

  bool _isDarkMode() {
    bool isDarkMode;
    final ThemeMode themeMode = Util.themeMode;
    if (themeMode == ThemeMode.light || themeMode == ThemeMode.dark) {
      isDarkMode = themeMode == ThemeMode.dark;
    } else {
      isDarkMode =
          WidgetsBinding.instance.window.platformBrightness == Brightness.dark;
    }
    return isDarkMode;
  }

  void _updateStatusBar() {
    final SystemUiOverlayStyle overlayStyle =
        _isDarkMode() ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark;
    SystemChrome.setSystemUIOverlayStyle(overlayStyle);
  }

  @override
  Widget build(BuildContext context) {
    if (_userModeLoaded == false && Util.preferences != null) {
      _userModeLoaded = true;
    }

    _updateStatusBar();
    final bool isDarkMode = _isDarkMode();
    final ThemeMode themeMode = Util.themeMode;
    final FLToastStyle style =
        isDarkMode ? FLToastStyle.light : FLToastStyle.dark;
    final FLToastDefaults toastDefaults = FLToastDefaults(
        style: style,
        position: _defaults.position,
        textDirection: Util.textDirection);

    return FLToastProvider(
      defaults: toastDefaults,
      child: MaterialApp(
        title: 'FLUI',
        debugShowCheckedModeBanner: false,
        themeMode: themeMode,
        theme: kLightTheme,
        darkTheme: kDarkTheme,
        routes: {
          HomeTab.routeName: (context) => HomeTab(),
          InputPage.routeName: (context) => InputPage(),
          EmptyPage.routeName: (context) => EmptyPage(),
          LoadingEmptyPage.routeName: (context) => LoadingEmptyPage(),
          HintsEmptyPage.routeName: (context) => HintsEmptyPage(),
          HintsActionEmptyPage.routeName: (context) => HintsActionEmptyPage(),
          ImageHintsEmptyPage.routeName: (context) => ImageHintsEmptyPage(),
          BadgePage.routeName: (context) => BadgePage(),
          LabelPage.routeName: (context) => LabelPage(),
          NoticeBarPage.routeName: (context) => NoticeBarPage(),
          SkeletonPage.routeName: (context) => SkeletonPage(),
          ActionSheetPage.routeName: (context) => ActionSheetPage(),
          AppBarPage.routeName: (context) => AppBarPage(),
          StaticListViewPage.routeName: (context) => StaticListViewPage(),
          ButtonPage.routeName: (context) => ButtonPage(),
          ToastPage.routeName: (context) => ToastPage(),
          BubblePage.routeName: (context) => BubblePage(),
          AvatarPage.routeName: (context) => AvatarPage(),
          InputPage.routeName: (context) => InputPage(),
          CountStepperPage.routeName: (context) => CountStepperPage()
        },
        builder: (BuildContext context, Widget child) {
          return Directionality(
            textDirection: Util.textDirection,
            child: child,
          );
        },
      ),
    );
  }
}

class HomeTab extends StatefulWidget {
  static const String routeName = '/';

  HomeTab({Key key, this.title}) : super(key: key);
  final String title;

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

class _HomeTabState extends State<HomeTab> {
  int _currentIndex = 0;
  List pages = [HomePage(), AboutPage()];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.apps),
            title: Text('widgets'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.info_outline),
            title: Text('about'),
          )
        ],
        currentIndex: _currentIndex,
        onTap: (index) => setState(() => _currentIndex = index),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  flui: ^0.8.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support 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:flui/flui.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
83
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
98
Overall:
Weighted score of the above. [more]
91
Learn more about scoring.

We analyzed this package on Feb 12, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.5
  • Flutter: 1.12.13+hotfix.7

Maintenance suggestions

Update README.md. (-2 points)

1 image link is insecure (e.g. http://img.shields.io/badge/read_the-docs-2196f3.svg), use https URLs instead.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test
mockito ^4.1.1