Snippets

Kevin Armstrong On-boarding - Exercise Example

Created by Kevin Armstrong

File circles_with_image.dart Added

  • Ignore whitespace
  • Hide word diff
+import 'package:flutter/material.dart';
+import 'dart:math';
+
+const double IMAGE_SIZE = 250.0;
+
+class CircleWithImage extends StatelessWidget {
+  final String image;
+
+  CircleWithImage(this.image);
+
+  Widget _centerCircle(double radius, double opacity){
+    return new Positioned(
+      width: radius,
+      child: Container(
+        width: radius,
+        height: radius,
+        decoration: BoxDecoration(
+          shape:  BoxShape.circle,
+          color: Colors.white.withOpacity(opacity),
+        ),
+      ),
+    );
+  }
+
+  Widget _largeCircle(Size size){
+    Random rnd = new Random();
+    double top = rnd.nextDouble();
+    double radius = rnd.nextDouble() * size.height;
+    double opacity = rnd.nextDouble() * 0.1;
+
+    return new Positioned(
+      top: top,
+      width: radius,
+      child: Container(
+        width: radius,
+        height: radius,
+        decoration: BoxDecoration(
+          shape:  BoxShape.circle,
+          color: Colors.white.withOpacity(opacity),
+        ),
+      ),
+    );
+  }
+
+  Widget _smallCircle(Size size){
+    Random rnd = new Random();
+    double top = rnd.nextDouble() * size.height;
+    double left = rnd.nextDouble() * size.width;
+    double radius = rnd.nextDouble() * 15.0;
+    double opacity = rnd.nextDouble() * 0.75;
+
+    return new Positioned(
+      top: top,
+      left: left,
+      width: radius,
+      child: Container(
+        width: radius,
+        height: radius,
+        decoration: BoxDecoration(
+          shape:  BoxShape.circle,
+          color: Colors.white.withOpacity(opacity),
+        ),
+      ),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final width = MediaQuery.of(context).size.width;
+    List<Widget> widgets = [];
+    List<Widget> smallCircles = List(10).map((_) => _smallCircle(MediaQuery.of(context).size)).toList();
+    List<Widget> largeCircles = List(5).map((_) => _largeCircle(MediaQuery.of(context).size)).toList();
+    List<Widget> centerCircles = [
+      _centerCircle(width * 1.35, 0.07),
+      _centerCircle(width * 1.25, 0.1),
+      _centerCircle(width * 1.0, 0.15),
+      _centerCircle(width * 0.40, 0.5),
+    ];
+    widgets.addAll(smallCircles);
+    widgets.addAll(largeCircles);
+    widgets.addAll(centerCircles);
+    /*
+    widgets.add(
+      SizedBox(
+        child: Image(
+          image: AssetImage(image),
+          fit: BoxFit.fitHeight,
+        ),
+        height: IMAGE_SIZE,
+        width: IMAGE_SIZE,
+      ),
+    );
+    */
+    return Stack(
+      children: widgets,
+      alignment: FractionalOffset.center,
+    );
+  }
+}

File dots_indicator.dart Added

  • Ignore whitespace
  • Hide word diff
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+
+class DotsIndicator extends AnimatedWidget {
+  DotsIndicator({
+    this.controller,
+    this.itemCount,
+    this.onPageSelected,
+    this.color: Colors.white,
+  }) : super(listenable: controller);
+
+  /// The PageController that this DotsIndicator is representing.
+  final PageController controller;
+
+  /// The number of items managed by the PageController
+  final int itemCount;
+
+  /// Called when a dot is tapped
+  final ValueChanged<int> onPageSelected;
+
+  /// The color of the dots.
+  ///
+  /// Defaults to `Colors.white`.
+  final Color color;
+
+  // The base size of the dots
+  static const double _kDotSize = 8.0;
+
+  // The increase in the size of the selected dot
+  static const double _kMaxZoom = 2.0;
+
+  // The distance between the center of each dot
+  static const double _kDotSpacing = 25.0;
+
+  Widget _buildDot(int index) {
+    double selectedness = Curves.easeOut.transform(
+      max(
+        0.0,
+        1.0 - ((controller.page ?? controller.initialPage) - index).abs(),
+      ),
+    );
+    double zoom = 1.0 + (_kMaxZoom - 1.0) * selectedness;
+    return new Container(
+      width: _kDotSpacing,
+      child: new Center(
+        child: new Material(
+          color: color,
+          type: MaterialType.circle,
+          child: new Container(
+            width: _kDotSize * zoom,
+            height: _kDotSize * zoom,
+            child: new InkWell(
+              onTap: () => onPageSelected(index),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  Widget build(BuildContext context) {
+    return new Row(
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: new List<Widget>.generate(itemCount, _buildDot),
+    );
+  }
+}

File main.dart Added

  • Ignore whitespace
  • Hide word diff
+import 'package:fluids/designs/onboarding/dots_indicator.dart';
+import 'package:flutter/material.dart';
+import './Page1.dart';
+import './Page2.dart';
+import './Page3.dart';
+
+class _OnboardingMainPageState extends State<OnboardingMainPage> {
+  final _controller = new PageController();
+  final List<Widget> _pages = [
+    Page1(),
+    Page2(),
+    Page3(),
+  ];
+  int page = 0;
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    bool isDone = page == _pages.length - 1;
+    return new Scaffold(
+      backgroundColor: Colors.transparent,
+      body: new Stack(
+        children: <Widget>[
+          new Positioned.fill(
+            child: new PageView.builder(
+              physics: new AlwaysScrollableScrollPhysics(),
+              controller: _controller,
+              itemCount: _pages.length,
+              itemBuilder: (BuildContext context, int index) {
+                return _pages[index % _pages.length];
+              },
+              onPageChanged: (int p){
+                setState(() {
+                  page = p;
+                });
+              },
+            ),
+          ),
+          new Positioned(
+            top: 0.0,
+            left: 0.0,
+            right: 0.0,
+            child: new SafeArea(
+              child: AppBar(
+                backgroundColor: Colors.transparent,
+                elevation: 0.0,
+                primary: false,
+                title: Text('Onboarding Example'),
+                actions: <Widget>[
+                  FlatButton(
+                    child: Text(isDone ? 'DONE' : 'NEXT', style: TextStyle(color: Colors.white),),
+                    onPressed: isDone ? (){
+                      Navigator.pop(context);
+                    } : (){
+                      _controller.animateToPage(page + 1, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
+                    },
+                  )
+                ],
+              ),
+            ),
+          ),
+          new Positioned(
+            bottom: 10.0,
+            left: 0.0,
+            right: 0.0,
+            child: new SafeArea(
+              child: new Column(
+                children: <Widget>[
+                  new Padding(
+                    padding: const EdgeInsets.all(8.0),
+                    child: new DotsIndicator(
+                      controller: _controller,
+                      itemCount: _pages.length,
+                      onPageSelected: (int page) {
+                        _controller.animateToPage(
+                          page,
+                          duration: const Duration(milliseconds: 300),
+                          curve: Curves.ease,
+                        );
+                      },
+                    ),
+                  ),
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+                    children: <Widget>[
+                      new Container(
+                        width: 150.0,
+                        height: 50.0,
+                        decoration: BoxDecoration(
+                          gradient: new LinearGradient(
+                            colors: [
+                              Colors.orange[600],
+                              Colors.orange[900],
+                            ],
+                            begin: Alignment(0.5, -1.0),
+                            end: Alignment(0.5, 1.0)
+                          ),
+                          borderRadius: new BorderRadius.circular(30.0),
+                        ),
+                        child: new Material(
+                          child: MaterialButton(
+                            child: Text('I\'M NEW',
+                              style: Theme.of(context).textTheme.button.copyWith(color: Colors.white),
+                            ),
+                            onPressed: (){},
+                            highlightColor: Colors.orange.withOpacity(0.5),
+                            splashColor: Colors.orange.withOpacity(0.5),
+                          ),
+                          color: Colors.transparent,
+                          borderRadius: new BorderRadius.circular(30.0),
+                        ),
+                      ),
+                      new Container(
+                        width: 150.0,
+                        height: 50.0,
+                        decoration: BoxDecoration(
+                          borderRadius: new BorderRadius.circular(30.0),
+                          border: Border.all(color: Colors.white, width: 1.0),
+                          color: Colors.transparent,
+                        ),
+                        child: new Material(
+                          child: MaterialButton(
+                            child: Text('LOG IN',
+                              style: Theme.of(context).textTheme.button.copyWith(color: Colors.white),
+                            ),
+                            onPressed: (){},
+                            highlightColor: Colors.white30,
+                            splashColor: Colors.white30,
+                          ),
+                          color: Colors.transparent,
+                          borderRadius: new BorderRadius.circular(30.0),
+                        ),
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ],
+      )
+    );
+  }
+}
+
+class OnboardingMainPage extends StatefulWidget {
+  OnboardingMainPage({Key key}) : super(key: key);
+
+  @override
+  _OnboardingMainPageState createState() => new _OnboardingMainPageState();
+}

File page1.dart Added

  • Ignore whitespace
  • Hide word diff
+import 'package:fluids/designs/onboarding/circles_with_image.dart';
+import 'package:fluids/utils/assets.dart';
+import 'package:flutter/material.dart';
+
+class Page1 extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return new Container(
+      height: double.infinity,
+      width: double.infinity,
+      decoration: new BoxDecoration(
+        gradient: LinearGradient(
+          colors: [
+            Colors.green[400],
+            Colors.blue[600],
+            Colors.blue[900],
+          ],
+          begin: Alignment(0.5, -1.0),
+          end: Alignment(0.5, 1.0)
+        )
+      ),
+      child: Stack(
+        children: <Widget>[
+          new Positioned(
+            child: new CircleWithImage(Assets.pose1),
+            width: MediaQuery.of(context).size.width,
+            height: MediaQuery.of(context).size.height,
+          ),
+          new Positioned.fill(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: <Widget>[
+                SizedBox(
+                  child: Image(
+                    image: AssetImage(Assets.pose1),
+                    fit: BoxFit.fitHeight,
+                  ),
+                  height: IMAGE_SIZE,
+                  width: IMAGE_SIZE,
+                ),
+                new Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: Text('Workout at home, outside or in the studio',
+                    style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white),
+                    textAlign: TextAlign.center,
+                  ),
+                ),
+                Text('Workout anywhere without any equipment!',
+                  style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
+                  textAlign: TextAlign.center,
+                )
+              ],
+            ),
+          )
+        ],
+        alignment: FractionalOffset.center,
+      ),
+    );
+  }
+}

File page2.dart Added

  • Ignore whitespace
  • Hide word diff
+import 'package:fluids/designs/onboarding/circles_with_image.dart';
+import 'package:fluids/utils/assets.dart';
+import 'package:flutter/material.dart';
+
+const double IMAGE_SIZE = 200.0;
+
+class Page2 extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return new Container(
+      height: double.infinity,
+      width: double.infinity,
+      decoration: new BoxDecoration(
+        gradient: LinearGradient(
+          colors: [
+            Colors.pink[400],
+            Colors.deepPurple[600],
+            Colors.deepPurple[900],
+          ],
+          begin: Alignment(0.5, -1.0),
+          end: Alignment(0.5, 1.0)
+        )
+      ),
+      child: Stack(
+        children: <Widget>[
+          new Positioned(
+            child: new CircleWithImage(Assets.pose2),
+            width: MediaQuery.of(context).size.width,
+            height: MediaQuery.of(context).size.height,
+          ),
+          new Positioned.fill(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: <Widget>[
+                SizedBox(
+                  child: Image(
+                    image: AssetImage(Assets.pose2),
+                    fit: BoxFit.fitHeight,
+                  ),
+                  height: IMAGE_SIZE,
+                  width: IMAGE_SIZE,
+                ),
+                new Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: Text('Varied Workouts\nBuilt Skills',
+                    style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white),
+                    textAlign: TextAlign.center,
+                  ),
+                ),
+                Text('Take your workouts to the next level\nand become a BEAST!',
+                  style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
+                  textAlign: TextAlign.center,
+                )
+              ],
+            ),
+          )
+        ],
+        alignment: FractionalOffset.center,
+      ),
+    );
+  }
+}

File page3.dart Added

  • Ignore whitespace
  • Hide word diff
+import 'package:fluids/designs/onboarding/circles_with_image.dart';
+import 'package:fluids/utils/assets.dart';
+import 'package:flutter/material.dart';
+
+const double IMAGE_SIZE = 300.0;
+
+class Page3 extends StatelessWidget {
+  @override
+  Widget build(BuildContext context) {
+    return new Container(
+      height: double.infinity,
+      width: double.infinity,
+      decoration: new BoxDecoration(
+        gradient: LinearGradient(
+          colors: [
+            Colors.orange[400],
+            Colors.red[600],
+            Colors.red[900],
+          ],
+          begin: Alignment(0.5, -1.0),
+          end: Alignment(0.5, 1.0)
+        )
+      ),
+      child: Stack(
+        children: <Widget>[
+          new Positioned(
+            child: new CircleWithImage(Assets.pose3),
+            width: MediaQuery.of(context).size.width,
+            height: MediaQuery.of(context).size.height,
+          ),
+          new Positioned.fill(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: <Widget>[
+                SizedBox(
+                  child: Image(
+                    image: AssetImage(Assets.pose3),
+                    fit: BoxFit.fitHeight,
+                  ),
+                  height: IMAGE_SIZE,
+                  width: IMAGE_SIZE,
+                ),
+                new Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: Text('Learn the secret techniques',
+                    style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white),
+                    textAlign: TextAlign.center,
+                  ),
+                ),
+                Text('Our programs have been tested\nby professional instructors & athletes.',
+                  style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
+                  textAlign: TextAlign.center,
+                )
+              ],
+            ),
+          )
+        ],
+        alignment: FractionalOffset.center,
+      ),
+    );
+  }
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.