A powerful UI framework for Google Flutter.

Last update: May 14, 2022

English | 简体中文


FLUI

A powerful UI framework 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
  • Dynamic rendering module -- Dynamic

Compatibility

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

Currently supports v1.17.0 .

Getting Started

Setup

dependencies:
  flui: 0.9.2

Then run flutter pub get to download the dependencies.

Usage

After the dependency installed, you can directly import the widget.

import 'package:flui/flui.dart';

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

Widgets

Dynamic

dynamic-post

FLUI-Dynamic is a dynamic rendering module that supports rendering widgets based on json strings or objects of a specified type. For more introduction and usage, please see Dynamic

Widget buildDynamicWidget() {
    return FLDyContainer(
       jsonObject: $JSON_STRING_OR_OBJECT,
       placeholder: CircularProgressIndicator(
         strokeWidth: 3.0,
         valueColor: AlwaysStoppedAnimation(Theme.of(context).accentColor),
       ),
    );
}

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

GitHub

https://github.com/Rannie/flui
Comments
  • 1. [input] long press the input widget will crash

    step

    1.run the flui demo 2.open the Input page 3.long press the input widget will crash

    flutter doctor:

    Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, v1.17.0, on Mac OS X 10.15.4 19E287, locale zh-Hans-CN) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.4) [✓] Android Studio (version 3.6) [✓] Connected device (2 available) • No issues found!

    crash info

    WechatIMG37

    Reviewed by JellyHell at 2020-05-08 03:16
  • 2. can't use it

    E/flutter ( 6877): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Bad state: No element
    E/flutter ( 6877): #0      Iterable.first (dart:core/iterable.dart:520:7)
    E/flutter ( 6877): #1      _showToast (package:flui/widgets/toast.dart:186:45)
    E/flutter ( 6877): #2      FLToast.showInfo (package:flui/widgets/toast.dart:164:7)
    E/flutter ( 6877): #3      FLToast.info (package:flui/widgets/toast.dart:158:46)
    E/flutter ( 6877): #4      _LoginPageState._getAccessTokenHandle (package:whale/pages/login/login_page.dart:169:15)
    E/flutter ( 6877): <asynchronous suspension>
    E/flutter ( 6877): #5      _LoginPageState._buildSignIn.<anonymous closure> (package:whale/pages/login/login_page.dart:407:32)
    E/flutter ( 6877): #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
    E/flutter ( 6877): #7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
    E/flutter ( 6877): #8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
    E/flutter ( 6877): #9      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7)
    E/flutter ( 6877): #10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9)
    E/flutter ( 6877): #11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
    E/flutter ( 6877): #12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9)
    E/flutter ( 6877): #13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
    E/flutter ( 6877): #14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18)
    E/flutter ( 6877): #15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7)
    E/flutter ( 6877): #16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
    E/flutter ( 6877): #17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
    E/flutter ( 6877): #18     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
    E/flutter ( 6877): #19     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
    E/flutter ( 6877): #20     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
    E/flutter ( 6877): #21     _rootRunUnary (dart:async/zone.dart:1138:13)
    E/flutter ( 6877): #22     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
    E/flutter ( 6877): #23     _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
    E/flutter ( 6877): #24     _invoke1 (dart:ui/hooks.dart:273:10)
    E/flutter ( 6877): #25     _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)
    
    
    Reviewed by li-xunhuan at 2019-12-23 12:54
  • 3. 使用 Toast 导致 文本框双击就报错

    环境: flutter SDK - 1.17.0 flui: ^0.9.1

    错误

    The following assertion was thrown building _OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#802fc](dirty, state: _OverlayEntryWidgetState#171e5): No MediaQuery widget found.

    _OverlayEntryWidget widgets require a MediaQuery widget ancestor. The specific widget that could not find a MediaQuery ancestor was: _OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#802fc] dirty state: _OverlayEntryWidgetState#171e5 The ownership chain for the affected widget is: "_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#802fc] ← _Theatre ← Overlay ← Stack ← Directionality ← _FLToastDefaultsWidget ← FLToastProvider ← MyApp ← _InheritedProviderScope ← ChangeNotifierProvider ← ⋯"

    Typically, the MediaQuery widget is introduced by the MaterialApp or WidgetsApp widget at the top of your application widget tree.

    Reviewed by Exclusive-gfj at 2020-05-12 09:37
  • 4. Enabled params missing into FLRaisedButton

    Hi, I see you lib and use it in my app but I know that you have forgot to add "enabled" property to FLRaisedButton and FLLoadingButton

    Regards

    Reviewed by carmas123 at 2020-05-10 15:05
  • 5. Add “Why this” to README

    There is nothing in the README to indicate why I might choose this over the standard widgets. Please add a paragraph near the top of the README about why I might want to use this project.

    Reviewed by gisborne at 2020-01-28 05:33
  • 6. button in FLToast is unclickable

    demo code: ` toast(String value, {String buttonTitle = 'Dismiss', Function onButtonPress}) { Function dismiss; dismiss = FLToast.showToast( text: value, duration: Duration(seconds: 5), contentBuilder: (cx){ return FlatButton( onPressed: () { if (onButtonPress == null) { dismiss(); } else { onButtonPress(); } }, child: Text( buttonTitle, style: TextStyle(color: Colors.amber, fontSize: 18), ), ); } ); }

    `

    Reviewed by Mohammad-Adam at 2020-04-09 19:48
  • 7. FLMarqueeLabel 和 easy_refresh 事件冲突

    FLMarqueeLabel内容滚动的时候,easy_refresh刷新和上拉加载不会响应。

    import 'package:flutter_easyrefresh/easy_refresh.dart';
    import 'package:flui/flui.dart';
    
    class CategoryPage extends StatefulWidget {
      CategoryPage({Key key}) : super(key: key);
      @override
      _CategoryPageState createState() => _CategoryPageState();
    }
    
    class _CategoryPageState extends State<CategoryPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('分类')),
          body: EasyRefresh(
            child: ListView(
              children: <Widget>[
                FLMarqueeLabel(
                  text: 'Notice: FLUI is a widget kit for Google Flutter',
                  style: TextStyle(color: Colors.blueAccent, fontSize: 16),
                  velocity: 1,
                  space: 150,
                  loop: true,
                )
              ],
            ),
            onRefresh: () {},
            onLoad: () {},
          ),
        );
      }
    }```
    Reviewed by IvanYue at 2020-03-20 06:36
  • 8. chore(deps): bump addressable from 2.7.0 to 2.8.0 in /example/ios

    Bumps addressable from 2.7.0 to 2.8.0.

    Changelog

    Sourced from addressable's changelog.

    Addressable 2.8.0

    • fixes ReDoS vulnerability in Addressable::Template#match
    • no longer replaces + with spaces in queries for non-http(s) schemes
    • fixed encoding ipv6 literals
    • the :compacted flag for normalized_query now dedupes parameters
    • fix broken escape_component alias
    • dropping support for Ruby 2.0 and 2.1
    • adding Ruby 3.0 compatibility for development tasks
    • drop support for rack-mount and remove Addressable::Template#generate
    • performance improvements
    • switch CI/CD to GitHub Actions
    Commits
    • 6469a23 Updating gemspec again
    • 2433638 Merge branch 'main' of github.com:sporkmonger/addressable into main
    • e9c76b8 Merge pull request #378 from ashmaroli/flat-map
    • 56c5cf7 Update the gemspec
    • c1fed1c Require a non-vulnerable rake
    • 0d8a312 Adding note about ReDoS vulnerability
    • 89c7613 Merge branch 'template-regexp' into main
    • cf8884f Note about alias fix
    • bb03f71 Merge pull request #371 from charleystran/add_missing_encode_component_doc_entry
    • 6d1d809 Adding note about :compacted normalization
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2021-07-13 06:24
  • 9. FLToast

    Getting exception of on calling Toast Screen Shot 2021-06-03 at 7 36 18 PM

    ════════ Exception caught by gesture ═══════════════════════════════════════════ Bad state: No element

    flutter --version Flutter 2.0.6 • channel stable • https://github.com/flutter/flutter.git Framework • revision 1d9032c7e1 (5 weeks ago) • 2021-04-29 17:37:58 -0700 Engine • revision 05e680e202 Tools • Dart 2.12.3 FLui: ^0.9.2

    Edit: Found Ans need to wrap widget on Provider https://www.flui.xin/en/widgets/toast.html#fltoastprovider

    Reviewed by ParasRai2 at 2021-06-03 13:52
  • 10. version solving failed

    Because flui >=0.9.0 depends on json_annotation ^3.0.1 and neat_periodic_task 2.0.0 depends on json_annotation ^4.0.0, flui >=0.9.0 is incompatible with neat_periodic_task 2.0.0. So, because new_box depends on both neat_periodic_task 2.0.0 and flui 0.9.2, version solving failed. pub get failed (1; So, because new_box depends on both neat_periodic_task 2.0.0 and flui 0.9.2, version solving failed.)

    Reviewed by alg520 at 2021-12-20 09:19
  • 11. FLStaticListView 使用,当sections元素很多的时候不能支持页面滚动吗?

    测试源码

    import 'package:flui/flui.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    /// 用户中心页面
    class UserSettingPage extends StatefulWidget {
      UserSettingPage({Key key}) : super(key: key);
    
      @override
      _UserSettingPageState createState() => _UserSettingPageState();
    }
    
    class _UserSettingPageState extends State<UserSettingPage> with RouteAware {
      // 点击底部退出按钮
      willSelectLogout() {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return AlertDialog(
              content: SingleChildScrollView(
                child: ListBody(
                  children: <Widget>[
                    Padding(
                      padding: EdgeInsets.only(top: 40),
                    ),
                    GestureDetector(
                      onTap: () {},
                      child: Text('   退出登录'),
                    ),
                    Padding(
                      padding: EdgeInsets.only(bottom: 20),
                    ),
                    Padding(
                      padding: EdgeInsets.only(bottom: 20),
                    ),
                    GestureDetector(
                      onTap: () async {
                        await SystemChannels.platform
                            .invokeMethod('SystemNavigator.pop');
                      },
                      child: Text('   退出程序'),
                    ),
                  ],
                ),
              ),
              actions: <Widget>[
                FlatButton(
                  child: Text('取消'),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            );
          },
        ).then((val) {
          print(val);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: FLAppBarTitle(
              title: '设置',
              // subtitle: '(subtitle)',
            ),
            centerTitle: true,
          ),
          body: Container(
            child: ListView(
              children: [
                // 头像
                Container(
                  child: Column(
                    children: [
                      Padding(padding: EdgeInsets.only(top: 23)),
                      GestureDetector(
                        child: Container(
                            width: 80,
                            height: 80,
                            decoration: BoxDecoration(
                              shape: BoxShape.rectangle,
                              borderRadius: BorderRadius.circular(80),
                              image: DecorationImage(
                                  image: NetworkImage(
                                      'https://www.dogedoge.com/rmt/QjmnZnf7-99_14oATuI2m-o6Gl5lNXUKPLEVtOSdermAm8fTGOx8mchN4?w=212&h=130'),
                                  fit: BoxFit.cover),
                            )),
                        onTap: () {},
                      ),
                      Padding(padding: EdgeInsets.only(bottom: 20)),
                      GestureDetector(
                        onTap: () {},
                        child: Text(
                          '点击修改头像',
                          style: TextStyle(fontSize: 12, color: Color(0xFF999999)),
                        ),
                      )
                    ],
                  ),
                ),
                FLStaticListView(
                  shrinkWrap: true,
                  sections: [
                    FLStaticSectionData(headerTitle: '账号', itemList: [
                      FLStaticItemData(
                          title: '账号管理',
                          accessoryType: FLStaticListCellAccessoryType.accDetail,
                          onTap: null),
                      FLStaticItemData(
                          title: '账号与安全',
                          accessoryType: FLStaticListCellAccessoryType.accDetail,
                          onTap: null),
                    ]),
                    FLStaticSectionData(headerTitle: '设置', itemList: [
                      FLStaticItemData(
                          title: '推送通知设置',
                          accessoryType: FLStaticListCellAccessoryType.accDetail,
                          accessoryString: '全部通知',
                          onTap: () => {}),
                      FLStaticItemData(
                        title: '护眼模式',
                        accessoryType: FLStaticListCellAccessoryType.accSwitch,
                        accItemValue: true,
                        onButtonPressed: () {
                          print('onButtonPressed');
                        },
                        onTap: () => {print('onTap')},
                      ),
                      FLStaticItemData(
                        title: '自动清理缓存',
                        subtitle: '每 10 天清理一次',
                        accessoryType: FLStaticListCellAccessoryType.accCheckmark,
                        onTap: null,
                        selected: false,
                      )
                    ]),
                    FLStaticSectionData(itemList: [
                      FLStaticItemData(
                          cellType: FLStaticListCellType.button,
                          buttonTitle: '退出登录',
                          buttonTitleColor: Colors.blue,
                          onButtonPressed: () {
                            print('button pressed');
                          }),
                      FLStaticItemData(
                          cellType: FLStaticListCellType.button,
                          buttonTitle: '退出程序',
                          buttonTitleColor: Colors.red,
                          onButtonPressed: () {
                            willSelectLogout();
                          })
                    ])
                  ],
                ),
              ],
            ),
          ),
        );
      }
    }
    
    
    Reviewed by jcleng at 2020-05-29 03:59

Related

Flutter_news - News application developed for practice, learning and testing the potential of this powerful Framework Flutter
Flutter_news - News application developed for practice, learning and testing the potential of this powerful Framework Flutter

flutter_news News application developed for practice, learning and testing the potential of this powerful Google's UI toolkit. Resources Packages pub

May 14, 2022
The ROHD Verification Framework is a hardware verification framework built upon ROHD for building testbenches.
The ROHD Verification Framework is a hardware verification framework built upon ROHD for building testbenches.

ROHD Verification Framework The ROHD Verification Framework (ROHD-VF) is a verification framework built upon the Rapid Open Hardware Development (ROHD

Apr 4, 2022
Simple tool to open WhatsApp chat without saving the number, developed using Google's Flutter Framework. for Android/ IOS/ Desktop/ Web
Simple tool to open WhatsApp chat without saving the number, developed using Google's Flutter Framework. for Android/ IOS/ Desktop/ Web

OpenWp Simple tool to open WhatsApp chat without saving the number Explore the docs » View Demo · Report Bug · Request Feature Table of Contents About

Mar 5, 2022
Prism is a beautiful open-source wallpapers app for Android. It is built with Dart on top of Google's Flutter Framework.
Prism is a beautiful open-source wallpapers app for Android. It is built with Dart on top of Google's Flutter Framework.

Prism Prism is a beautiful open-source wallpapers app for Android. It is built with Dart on top of Google's Flutter Framework. Prism brings you exclus

May 20, 2022
Dart Web API Template Using Google Shelf Framework and Postgres Drivers, read readme to learn how to use

Shelf Web Framework Template by Alex Merced of AlexMercedCoder.com Cloning the Template git clone https://github.com/AlexMercedCoder/DartShelfPostgres

May 11, 2022
Flutter google maps - Flutter google maps Example
Flutter google maps - Flutter google maps Example

google_maps_example Development Setup Clone the repository and run the following

May 2, 2022
A Demo application📱 which stores User feedback from 💙Flutter application into Google Sheets🗎 using Google AppScript.
A Demo application📱  which stores User feedback from 💙Flutter application into Google Sheets🗎 using Google AppScript.

?? Flutter ?? to Google Sheets ?? A Demo application which stores User feedback from Flutter application into Google Sheets using Google AppScript. Yo

May 18, 2022
Google mobile ads applovin - AppLovin mediation plugin for Google Mobile Ads (Flutter).

AppLovin mediation plugin for Google Mobile Ads Flutter Google Mobile Ads Flutter mediation plugin for AppLovin. Use this package as a library depende

Jan 2, 2022
Google one tap sign in - Flutter Google One Tap Sign In (Android)
Google one tap sign in - Flutter Google One Tap Sign In (Android)

Google One Tap Sign In Google One Tap Sign In (Android) A Flutter Plugin for Goo

Feb 11, 2022
A google browser clone which is made by using flutter and fetching the google search api for the search requests.
A google browser clone which is made by using flutter and fetching the google search api for the search requests.

google_clone A new Flutter project. Project Preview Getting Started This project is a starting point for a Flutter application. A few resources to get

Jan 12, 2022
Google-news-app-redesign - Redesigned the ui of google news app with flutter
Google-news-app-redesign - Redesigned the ui of google news app with flutter

News app like Google news! ScreenShots If you face any problem with this project

Mar 5, 2022
Get google api credentials - A Dart CLI app to obtain credentials for accessing Google APIs

get_google_api_credentials A Dart CLI app to obtain credentials for accessing Go

Jan 28, 2022
This is an open source Tips & Tricks for Flutter, that helps flutter Developers write simple but powerful dart codes.

Showcasing-flutter - This is an open source Tips & Tricks for Flutter, that helps flutter Developers write simple but powerful dart codes.

Jan 4, 2022
Flutter Transition UI - Create powerful UI design animations easily with Flutter
Flutter Transition UI - Create powerful UI design animations easily with Flutter

Transition Animation - Locations UI Design - Flutter Create powerful UI design a

May 18, 2022
A quick and powerful Flutter layout with a bottom navbar.
A quick and powerful Flutter layout with a bottom navbar.

What is bottom_nav_layout? It is a quick flutter app layout for building an app with a bottom nav bar. You can get an app with fluent behavior running

Feb 19, 2022
🎯 A powerful multiplatform application with Flutter and Supabase for the Komentory project.

?? Multiplatform application for Komentory project A powerful multiplatform application with Flutter and Supabase for the Komentory project. Currently

Mar 1, 2022
Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern.
Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern.

Karee Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern. + = About Karee Karee is a frame

May 4, 2022
Flutter Scrollable Widgets like ListView,GridView or powerful CustomScrollView can't nest inner scrollview

Introduction Flutter Scrollable Widgets like ListView,GridView or powerful CustomScrollView can't nest inner scrollview. If Nested, inner scrollview w

Mar 4, 2022