adaptive_library 0.3.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 75

adaptive_library #

A set of Widgets that create a native look and feel on iOS and Android.

Flutter already gives us a great library for Material and Cupertino widgets. But as a cross platform tool, Flutter does not provide a good way of displaying the right widget design types on each platform dynamically.

adaptive_library crashes in and... here it is!

Getting Started #

To get started, import the package to your app, after getting the package.

import 'package:adaptive_library/adaptive_library.dart';

The widgets #

Our library currently contains 9 widgets that can be used to create a native look and feel on iOS and Android devices. There are more in the future, so stay tuned.

Most of the time, you can replace the base class name of a widget with the ones from this library. You do not need to rename or remove parameters; though at some points you eventually need to add one parameter (This makes adaptive_library great, huh?)

Important things in advance #

adaptive_library uses the concept of InheritedWidget to get access to the current platform. This makes sure that you do not need to reenter Platform.isAndroid || Platform.isIOS or whatever, every time you need a widget. And yes, "Fluttering" is done by widgets, so this would be... nah. ;)

AdaptiveInheritance #

AdaptiveInheritance is the core class. Every adaptive widget needs it, because it defines the Platform "state" (-> Android or iOS).

AdaptiveInheritance(
      adaptiveState: AdaptiveState.Cupertino,
      child: AdaptiveApp(
          //
      ),
    );

Typically, AdaptiveInheritance is the parent of the whole app. It enabled the functionality to reload all the widgets that are based on Platform state at the same time.

adaptiveState is set by an enum containing the fields; ***and if you want to set it dynamically, simply call AdaptiveInheritance.getStateByPlatform()***. This method uses Dart's io package to find out which Platform the app is currently running on, providing the correct AdaptiveState.

In this example, the direct child is AdaptiveApp, that combines MaterialApp and CupertinoApp.

AdaptiveApp #

AdaptiveApp(
        home: HomeScreenPage(),
      )

Use this to enable Material or Cupertino design for your app. Like the "originals", you can set parameters like debugShowCheckedModeBanner and home to define your app. The full list of parameters are growing, and can be inspected in the class.

Theming #

materialTheme and cupertinoTheme is used to apply the correct themeData to your app.

AdaptiveScaffold #

This is a cool thing.

AdaptiveScaffold(
      title: Text('Tests Page'),
      body: Text('Your content'),
      actions: []
    )

This is a replacement for Scaffold and CupertinoScaffold and combines them both. The title is set in the AppBar (CupertinoNavigationBar) and also, actions can be provided via actions field.

On Cupertino, the default CupertinoNavigationBar is used. To get one with large title, simply

AdaptiveScaffold.large(
      //...
    )

This has no effect on Material style.

Custom AppBar (CupertinoNavigationBar)

If you want to have you app bar customized, set either the appBar or cupertinoNavigationBar property on AdaptiveScaffold.

Key #

You can of course assign a key to the Scaffolds, to show a SnackBar for example. The field is scaffoldKey.

AdaptiveButton #

AdaptiveButton(
    child: Text('Your child'),
    onPressed: () => null,
)

As you can see, you can simply replace FlatButton, CupertinoButton or other buttons by AdaptiveButton. No need to change parameters.

You can specify a color for Material button style, but it is recommended to set via the theme in AdaptiveApp.

Raised/filled #

The code, by default, creates a FlatButton or CupertinoButton respectively. To use raised or filled version, append .raised like so:

AdaptiveButton.raised(
    //...
)

AdaptiveIconButton #

AdaptiveIconButton(
          icon: Icon(Icons.check_circle_outline),
          iconCupertino: Icon(CupertinoIcons.check_mark_circled),
          onPressed: () => null,
        )

Flutter currently has no Cupertino equivalent to IconButton, so AdaptiveIconButton makes it. Provide either an icon to use it on both designs, or define another icon for Cupertino, because CupertinoIcons look a bit different.

Here, you can also replace IconButton by AdaptiveIconButton without extra work

AdaptiveAlertDialog #

To use a platform based alert dialog, it is recommended to use AdaptiveAlertDialog.show instead of using it as a widget.

AdaptiveAlertDialog.show<String>(
              context,
              adaptiveState: AdaptiveInheritance.getStateByPlatform(),
              title: Text('Hallo'),
              content: Text('Einfach mal Hallo sagen'),
              actions: [],
            );

Unlike the other widgets, you need to set the AdaptiveState manually right now. (We're working on this).

show uses a generic parameter that lets you specify the data you want to return.

Notice: Using closeOnPress with AdaptiveAlertDialogButton, the dialog is dismissed without any parameter. To get the result of a dialog, go like the normal way and specify it inside the ActionButtons. See next section for more info.

The actions #

Because iOS devices do not have the typical "back" button by default, it is recommended to provide actions to dismiss the dialog. If you really do not want to use action buttons, set an empty array.

Define actions #

actions: [
  AdaptiveAlertDialogButton(
                child: Text('OK'),
                destructive: true,
                onPressed: () {
                    //do stuff here
                },
              ),
  AdaptiveAlertDialogButton(
                closeOnPress: true,
                child: Text('Thanks'),
                onPressed: null,
              ),
]

AdaptiveAlertDialogButton decides whether to use a FlatButton or a CupertinoDialogAction. You can leave out onPressed or set it to null; by setting closeOnPress to true, the dialog is dismissed, regardless of onPressed being set. In case closeOnPress is set to true, there will be no "return" value passed with Navigator.pop

Setting destructive enables the typically red colored button that indicates a "destructive/cancel" action in Cupertino styled dialogs.

AdaptiveProgressIndicator #

AdaptiveProgressIndicator()
AdaptiveProgressIndicator(value: 45)            

Either displays a CircularProgressIndicator or a CupertinoActivityIndicator. value is ignored on Cupertino style.

AdaptiveListTile #

AdaptiveListTile(
              title: Text('Brightness'),
              subtitle: Text('Change brightness'),
              onTap: () {
                //do stuff here.
              },
            )

On Cupertino, there is a little grey row with borders, like the typical settings entry known from iOS. leading, trailing and dense will not work on Cupertino.

What else? #

There are more widgets coming up in the future, so keep track!

I have an idea #

Great. Pull requests are very welcome!

[0.3.0] - Switch added

  • Flutter already has a Switch.adaptive, but the platform for this widget cannot dynamically be adjusted.

[0.2.9+2] - Fix Scaffold crash (2)

  • Check if large navBar for Cupertino.

[0.2.9+1] - Fix Scaffold crash

  • Null checks for app bars.

[0.2.9] - Improved AdaptiveScaffold

  • An AppBar is no longer required in AdaptiveScaffold.

[0.2.8] - Assertions in AdaptiveScaffold removed.

  • The're not useful. Title is auto ignored on a null app bar

[0.2.7] - Assertions in AdaptiveScaffold

  • Setting a title on AdaptiveScaffold requires the app bars to be null.
  • Not setting a title requires both app bars to be set.

[0.2.6] - Keys added to all widgets

  • All widgets now contain a key parameter.
  • AdaptiveScaffold contains a key "scaffoldKey".

[0.2.5] - Adjust Scaffold's data

  • If needed, a custom AppBar or CupertinoNavigationBar can now be used.

[0.2.4] - ListTile and ProgressIndicator added

  • Adding support for adaptive ListTile and ProgressIndicator.

[0.2.3] - Fixed onPressed null

  • Not setting onPressed on AdaptiveAlertDialogButton causes the app to crash

[0.2.2] - "Zero day patch"

  • Improved stability on AdaptiveScaffold
  • A guide for AdaptiveScaffold is now in README.md

[0.2.1] - 02.11.2019

  • Initially published version.
  • Set of 7 widgets that can easily be used.
  • Use README.md as a guide

example/README.md

Use of adaptive_library #

This example explains how you can use this library in your app.

Use this package as a library

1. Depend on it

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


dependencies:
  adaptive_library: ^0.3.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:adaptive_library/adaptive_library.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
50
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
75
Learn more about scoring.

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

  • Dart: 2.7.0
  • pana: 0.13.4
  • Flutter: 1.12.13+hotfix.5

Health suggestions

Fix lib/src/adaptive_inheritance.dart. (-0.50 points)

Analysis of lib/src/adaptive_inheritance.dart reported 1 hint:

line 26 col 20: 'inheritFromWidgetOfExactType' is deprecated and shouldn't be used. Use dependOnInheritedWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.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