platform_aware 0.4.0

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

platform_aware

Flutter widgets wrapped to automatically adapt to the current platform,
whereas no code changes are needed for supporting both iOS and Android.
All widgets depend on Theme.of(context).platform for determining the currently active platform.
This allows you to use the Flutter Inspector to change the platform on the fly.

Fuchsia was already considered in the design of this package.

Getting Started

Check the example, it includes example usages for all provided widgets.

Screenshots

Checkbox

drawing drawing

Card

drawing drawing

Dialog

drawing drawing

FlatButton

drawing drawing

RaisedButton

drawing drawing

Picker

Android

drawing drawing

iOS

drawing drawing

Tabs

drawing drawing

[0.3.2] - 18.07.2018

  • Added screenshots showing some selected widgets

[0.3.0] - 05.07.2018

  • PlatformAwareIconButton now takes an iconSize parameter, with the same semantics as IconButton

[0.2.8] - 29.06.2018

  • PlatformAwareIconButton: use Icon.size for button rendering

example/lib/main.dart

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

void main() => runApp(new DemoApp());

class DemoApp extends StatefulWidget {
  @override
  State createState() => new DemoAppState();
}

class DemoAppState extends State<DemoApp> {
  TargetPlatform targetPlatform = TargetPlatform.android;

  void _togglePlatform() =>
      setState(() => targetPlatform = (targetPlatform == TargetPlatform.android
          ? TargetPlatform.iOS
          : TargetPlatform.android));

  @override
  Widget build(BuildContext context) => new MaterialApp(
        title: 'Flutter Demo',
        initialRoute: '/',
        theme: new ThemeData.light().copyWith(platform: targetPlatform),
        routes: {
          '/': (BuildContext context) =>
              new MainMenu(togglePlatform: _togglePlatform),
          '/flatbutton': (BuildContext context) =>
              new FlatButtonDemo(togglePlatform: _togglePlatform),
          '/raisedbutton': (BuildContext context) =>
              new RaisedButtonDemo(togglePlatform: _togglePlatform),
          '/dialog': (BuildContext context) =>
              new AlertDialogDemo(togglePlatform: _togglePlatform),
          '/card': (BuildContext context) =>
              new CardDemo(togglePlatform: _togglePlatform),
          '/checkbox': (BuildContext context) =>
              new CheckboxDemo(togglePlatform: _togglePlatform),
          '/picker': (BuildContext context) =>
              new PickerDemo(togglePlatform: _togglePlatform),
          '/iconbutton': (BuildContext context) =>
              new IconButtonDemo(togglePlatform: _togglePlatform),
          '/tabs': (BuildContext context) =>
              new TabsDemo(togglePlatform: _togglePlatform),
        },
      );
}

class TabsDemo extends StatelessWidget {
  final VoidCallback togglePlatform;

  TabsDemo({@required this.togglePlatform});

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Tabs'),
        tabs: <PlatformAwareTabItem>[
          new PlatformAwareTabItem(text: 'Left', icon: Icons.arrow_left),
          new PlatformAwareTabItem(text: 'Right', icon: Icons.arrow_right),
        ],
        tabViewBuilder: (BuildContext context, int tabIndex) => new Center(
              child: new Text(
                (tabIndex == 0) ? 'Left tab!' : 'Right tab!',
                style: Theme.of(context).textTheme.display1,
              ),
            ),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: togglePlatform,
          ),
        ],
      );
}

class CardDemo extends StatelessWidget {
  final VoidCallback togglePlatform;

  CardDemo({@required this.togglePlatform});

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Card'),
        body: new ListView(
            children: new Iterable.generate(
                5,
                (_) => new Row(
                      children: <Widget>[
                        new Expanded(
                            child: new PlatformAwareCard(
                          title: new Text(
                            "Hello",
                            style: Theme.of(context).textTheme.headline,
                          ),
                          content: new Container(
                              padding: const EdgeInsets.all(4.0),
                              child: new Column(
                                children: <Widget>[
                                  new Text("Place any content here"),
                                  new Text("or here"),
                                  new Text("or here"),
                                ],
                              )),
                        ))
                      ],
                      mainAxisAlignment: MainAxisAlignment.center,
                    )).toList()),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: togglePlatform,
          ),
        ],
      );
}

class CheckboxDemo extends StatefulWidget {
  final VoidCallback togglePlatform;

  CheckboxDemo({@required this.togglePlatform});

  @override
  State createState() => new CheckboxDemoState();
}

class CheckboxDemoState extends State<CheckboxDemo> {
  Map<int, bool> checkState = new Map.fromIterable(
      new Iterable<int>.generate(30),
      value: (key) => key % 2 > 0);

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Checkbox'),
        body: new ListView(
            children: checkState.entries
                .map((MapEntry<int, bool> entry) => new PlatformAwareListTile(
                      title: new Text('Checkbox ${entry.key}',
                          style: Theme.of(context).textTheme.subhead),
                      onTap: () =>
                          setState(() => checkState[entry.key] = !entry.value),
                      trailing: new PlatformAwareCheckbox(
                        onChanged: (bool newChecked) =>
                            setState(() => checkState[entry.key] = newChecked),
                        value: entry.value,
                      ),
                    ))
                .toList()),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: widget.togglePlatform,
          ),
        ],
      );
}

class PickerDemo extends StatefulWidget {
  final VoidCallback togglePlatform;

  PickerDemo({@required this.togglePlatform});

  @override
  State createState() => new PickerDemoState();
}

class PickerDemoState extends State<PickerDemo> {
  int selectedIndex = 0;
  final List<Color> items = <Color>[
    Colors.deepOrange,
    Colors.purple,
    Colors.blue,
    Colors.green,
    Colors.yellow,
    Colors.black,
    Colors.lightGreenAccent
  ];

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Picker'),
        body: new Center(
            child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new PlatformAwareDecoration(title: 'Picker demo'),
            new PlatformAwarePicker<Color>(
              initialItemIndex: selectedIndex,
              items: items,
              onChanged: (Color selectedColor) =>
                  setState(() => selectedIndex = items.indexOf(selectedColor)),
              itemWidgetBuilder: (BuildContext context, Color item) => new Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    mainAxisSize: MainAxisSize.max,
                    children: <Widget>[
                      new Container(
                        width: 15.0,
                        height: 15.0,
                        color: item,
                        margin: const EdgeInsets.only(right: 10.0),
                      ),
                      new Text("Color #${items.indexOf(item)}"),
                    ],
                  ),
            ),
          ],
        )),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: widget.togglePlatform,
          ),
        ],
      );
}

class TogglePlatformAppBarButton extends StatelessWidget {
  final VoidCallback togglePlatform;

  TogglePlatformAppBarButton({@required this.togglePlatform});

  @override
  Widget build(BuildContext context) => new Container(
        child: new PlatformAwareIconButton(
            onPressed: togglePlatform,
            tooltip: 'Switch platform',
            icon: new Icon(Theme.of(context).platform != TargetPlatform.android
                ? Icons.android
                : Icons.smartphone)),
        padding: const EdgeInsets.only(right: 20.0),
      );
}

class MainMenu extends StatelessWidget {
  final VoidCallback togglePlatform;

  MainMenu({@required this.togglePlatform});

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('platforn_aware demo'),
        body: new ListView(
          children: ListTile
              .divideTiles(
                  tiles: <String>[
                    'Flatbutton',
                    'Raisedbutton',
                    'Iconbutton',
                    'Dialog',
                    'Card',
                    'Checkbox',
                    'Picker',
                    'Tabs'
                  ]
                      .map((String title) => new PlatformAwareListTile(
                            title: new Text(
                              title,
                              style: Theme.of(context).textTheme.subhead,
                            ),
                            onTap: () => Navigator
                                .of(context)
                                .pushNamed('/${title.toLowerCase()}'),
                          ))
                      .toList(),
                  color: Theme.of(context).dividerColor)
              .toList(growable: false),
        ),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: togglePlatform,
          ),
        ],
      );
}

class RaisedButtonDemoState extends State<RaisedButtonDemo> {
  int counter = 0;

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Button'),
        body: new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            new Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                new Text(
                  counter.toString(),
                  style: Theme.of(context).textTheme.display1,
                ),
                new PlatformAwareRaisedButton(
                  child: new Text("Click me"),
                  onPressed: () => setState(() => ++counter),
                )
              ],
            )
          ],
        ),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: widget.togglePlatform,
          ),
        ],
      );
}

class RaisedButtonDemo extends StatefulWidget {
  final VoidCallback togglePlatform;

  RaisedButtonDemo({@required this.togglePlatform});

  @override
  State createState() => new RaisedButtonDemoState();
}

class FlatButtonDemoState extends State<FlatButtonDemo> {
  int counter = 0;

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Button'),
        body: new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            new Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                new Text(
                  counter.toString(),
                  style: Theme.of(context).textTheme.display1,
                ),
                new PlatformAwareFlatButton(
                  child: new Text("Click me"),
                  onPressed: () => setState(() => ++counter),
                )
              ],
            )
          ],
        ),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: widget.togglePlatform,
          ),
        ],
      );
}

class FlatButtonDemo extends StatefulWidget {
  final VoidCallback togglePlatform;

  FlatButtonDemo({@required this.togglePlatform});

  @override
  State createState() => new FlatButtonDemoState();
}

class IconButtonDemoState extends State<IconButtonDemo> {
  final List<Color> colors = <Color>[
    Colors.redAccent,
    Colors.blueAccent,
    Colors.deepOrange,
    Colors.green,
    Colors.purple
  ];
  int selectedColorIndex = 0;

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('IconButton'),
        body: new Center(
          child: new PlatformAwareIconButton(
            iconSize: 100.0,
            icon: new Icon(
              Icons.settings,
              color: colors.elementAt(selectedColorIndex),
            ),
            onPressed: () => setState(() =>
                selectedColorIndex = (selectedColorIndex + 1) % colors.length),
            tooltip: 'Settings',
          ),
        ),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: widget.togglePlatform,
          ),
        ],
      );
}

class IconButtonDemo extends StatefulWidget {
  final VoidCallback togglePlatform;

  IconButtonDemo({@required this.togglePlatform});

  @override
  State createState() => new IconButtonDemoState();
}

class AlertDialogDemo extends StatelessWidget {
  final VoidCallback togglePlatform;

  AlertDialogDemo({@required this.togglePlatform});

  @override
  Widget build(BuildContext context) => new PlatformAwareScaffold(
        title: new Text('Dialog'),
        body: new Center(
          child: new PlatformAwareRaisedButton(
              onPressed: () => showDialog(
                  context: context,
                  builder: (BuildContext context) =>
                      new PlatformAwareAlertDialog(
                        title: new Text('Demo dialog'),
                        content: new Row(
                          children: <Widget>[
                            new Text('Some content'),
                            new PlatformAwareIcon(Icons.track_changes)
                          ],
                        ),
                        actions: <Widget>[
                          new PlatformAwareFlatButton(
                              onPressed: () => Navigator.of(context).pop(),
                              child: new Row(
                                children: <Widget>[
                                  new Text("Done"),
                                  new Icon(Icons.check)
                                ],
                              )),
                          new PlatformAwareFlatButton(
                              onPressed: () => Navigator.of(context).pop(),
                              child: new Row(
                                children: <Widget>[
                                  new Text("Close"),
                                  new Icon(Icons.close)
                                ],
                              ))
                        ],
                      )),
              child: new Text("Show dialog")),
        ),
        actions: <Widget>[
          new TogglePlatformAppBarButton(
            togglePlatform: togglePlatform,
          ),
        ],
      );
}

Use this package as a library

1. Depend on it

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


dependencies:
  platform_aware: ^0.4.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

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

3. Import it

Now in your Dart code, you can use:


import 'package:platform_aware/platform_aware.dart';
  
Version Uploaded Documentation Archive
0.4.0 Jul 19, 2018 Go to the documentation of platform_aware 0.4.0 Download platform_aware 0.4.0 archive
0.3.2 Jul 18, 2018 Go to the documentation of platform_aware 0.3.2 Download platform_aware 0.3.2 archive
0.3.1 Jul 18, 2018 Go to the documentation of platform_aware 0.3.1 Download platform_aware 0.3.1 archive
0.3.0 Jul 5, 2018 Go to the documentation of platform_aware 0.3.0 Download platform_aware 0.3.0 archive
0.2.8 Jun 29, 2018 Go to the documentation of platform_aware 0.2.8 Download platform_aware 0.2.8 archive
0.2.7 Jun 28, 2018 Go to the documentation of platform_aware 0.2.7 Download platform_aware 0.2.7 archive
0.2.6 Jun 28, 2018 Go to the documentation of platform_aware 0.2.6 Download platform_aware 0.2.6 archive
0.2.5 Jun 28, 2018 Go to the documentation of platform_aware 0.2.5 Download platform_aware 0.2.5 archive
0.2.4 Jun 28, 2018 Go to the documentation of platform_aware 0.2.4 Download platform_aware 0.2.4 archive
0.2.3 Jun 28, 2018 Go to the documentation of platform_aware 0.2.3 Download platform_aware 0.2.3 archive

All 19 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
37
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]
69
Learn more about scoring.

We analyzed this package on Sep 18, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.3
  • Flutter: 0.8.4

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Suggestions

Format lib/src/platform_aware_card.dart.

Run flutter format to format lib/src/platform_aware_card.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.24.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test
test ^0.12.0