Flutter Phase 8 - Control Summary

Keywords: Android github network snapshot JSON

Recently written front-end, not summarizing flutter's learning process, now summarize, about animation, layout, login, home page, routing, json formatting, drop-down refresh, picture loading preview, welcome page, focus question, live, upload pictures, page information transfer, these knowledge points.Because the official documents give few points of knowledge, mostly scattered API s, we can only peel off the functional writing through the summary of some great gods. If you can't understand it, google. If you can't remember, look at demo. If you write more, you can remember that people can slowly learn due to limited domestic resources in the early period, but to learn, if you still want to do APP, flutter will do it laterThere will certainly be a world, after all, a set of code three platforms, enterprise owners will be more or less favored because of the cost, so go ahead ~

Attachment: The effect map will be completed slowly because there are a few demo s. It has been written for three hours. Thank you for your support.

1.animated_container (zoom in and zoom out github:https://github.com/geeklx/flutter_app2/tree/master/app2/animated_container): AnimationContainer uses essentials and must pass in Duration to tell the animation the playing time. When animationContainer receives a new value, it will complement the animation based on the old value, for example, starting with a width of 100 and then giving itWith a new value of 0 and setState, the AnimationContainer will gradually change the width and height from 100 to 0, where the change curve is determined by Curve and defaults to Curves.linear.Actually, most of the animations are packaged well. Write more and write more. I really can't remember to watch demo. Memory is not as good as bad writing.

 

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AnimatedContainerDemo(),
    );
  }
}


/**
 * AnimationContainer Key usage points
 * Must pass in Duration to tell the animation when to play
 * When animationContainer receives a new value
 * Inter-patch animation based on old values
 * For example, after starting with a width and height of 100 and giving a new value of 0 and setState
 * AnimationContainer Will gradually change width from 100 to 0
 * Where the change curve is determined by Curve, the default is Curves.linear
 */
import 'package:flutter/material.dart';

class AnimatedContainerDemo extends StatefulWidget {
  @override
  _AnimatedContainerDemoState createState() => _AnimatedContainerDemoState();
}

class _AnimatedContainerDemoState extends State<AnimatedContainerDemo> {
  double _value = 255.0;

  _changeValue() => setState(() {
        _value = _value == 255.0 ? 80.0 : 255.0;
        print(_value);
      });

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        onTap: _changeValue, //Zoom in and out
        child: AnimatedContainer(
          curve: Curves.decelerate,
          duration: Duration(seconds: 1),
          width: _value,
          height: _value,
          child: FlutterLogo(),
        ),
      ),
    );
  }
}

2.animated_cross_fade (animated github:https://github.com/geeklx/flutter_app2/tree/master/app2/animated_cross_fade):

 

import 'package:flutter/material.dart';

class AnimatedCrossFadeDemo extends StatefulWidget {
  @override
  _AnimatedCrossFadeDemoState createState() => _AnimatedCrossFadeDemoState();
}

class _AnimatedCrossFadeDemoState extends State<AnimatedCrossFadeDemo> {
  bool _first = false;

  change() {
    setState(() {
      _first = _first ? false : true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        onTap: change, //Horizontal and Vertical Turn Animation
        child: AnimatedCrossFade(
          duration: const Duration(seconds: 2),
          firstChild: const FlutterLogo(
            style: FlutterLogoStyle.horizontal,
            size: 200.0,
          ),
          secondChild: const FlutterLogo(
            style: FlutterLogoStyle.stacked,
            size: 200.0,
          ),
          crossFadeState:
              _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
        ),
      ),
    );
  }
}

3.animated_floating_action_bar (floating button github:https://github.com/geeklx/flutter_app2/tree/master/app2/animated_floating_action_bar): This is the official demo

 

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

    4.animation_challenge(github:https://github.com/geeklx/flutter_app2/tree/master/app2/animation_challenge):

home: HeroDemo(), //add list item

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;

class HeroDemo extends StatefulWidget {
  @override
  _HeroDemoState createState() => _HeroDemoState();
}

class _HeroDemoState extends State<HeroDemo> {
  List<String> list;

  @override
  void initState() {
    super.initState();
    list = List.generate(20, (index) => "This is no.$index");
  }

  @override
  Widget build(BuildContext context) {
    timeDilation = 2.0;
    return Scaffold(
      appBar: AppBar(
        title: Text('Demo1'),
      ),
      body: ListView.builder(
          itemCount: list.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(list[index]),
            );
          }),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Hero(
        tag: "FloatingActionButton",
        child: FloatingActionButton(
          backgroundColor: Colors.blue,
          onPressed: () => Navigator.of(context)
              .push(MaterialPageRoute(builder: (context) => SecondPage())),
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  final FocusNode focusNode = FocusNode();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0.0,
        iconTheme: IconThemeData(
          color: Colors.black,
        ),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          ListView(
            shrinkWrap: true,
            padding: const EdgeInsets.symmetric(horizontal: 20.0),
            children: <Widget>[
              TextField(
                autofocus: true,
                focusNode: focusNode,
                maxLines: 5,
                decoration: InputDecoration.collapsed(
                    hintText: 'What do you want to add now ?'),
              ),
            ],
          ),
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Hero(
          tag: "FloatingActionButton",
          child: Padding(
            padding:
                const EdgeInsets.only(left: 12.0, right: 12.0, bottom: 6.0),
            child: ButtonTheme(
              height: 48.0,
              minWidth: double.infinity,
              child: RaisedButton(
                color: Colors.lightBlue,
                onPressed: () {},
                elevation: 10.0,
                child: Icon(
                  Icons.add,
                  color: Colors.white,
                ),
              ),
            ),
          )),
    );
  }
}

home: HideBottomBarDemo(), //Scroll to hide bottom navigation animation

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

class HideBottomBarDemo extends StatefulWidget {
  @override
  _HideBottomBarDemoState createState() => _HideBottomBarDemoState();
}

class _HideBottomBarDemoState extends State<HideBottomBarDemo>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation _animation;
  ScrollController _scrollController;

  void _judgeScroll() {
    if (_scrollController.position.userScrollDirection ==
        ScrollDirection.reverse) {
      _animationController.forward();
    }
    if (_scrollController.position.userScrollDirection ==
        ScrollDirection.forward) {
      _animationController.reverse();
    }
  }

  @override
  void initState() {
    super.initState();
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
    _animation = Tween(begin: 0.0, end: -100.0).animate(CurvedAnimation(
        parent: _animationController, curve: Curves.fastOutSlowIn));
    _scrollController = ScrollController(keepScrollOffset: true)
      ..addListener(_judgeScroll);
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _animationController?.dispose();
    _scrollController..removeListener(_judgeScroll);
    //If the ScrollController is destroyed, the keepScrollOffset will be empty
    // _scrollController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Immersive BottomNavigationBar'),
      ),
      body: _buildListView(),
      bottomNavigationBar: _buildBottomNavigationBar(context),
    );
  }

  Widget _buildBottomNavigationBar(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return Container(
          height: 0.0,
          child: Stack(
            overflow: Overflow.visible,
            children: <Widget>[
              Positioned(
                  bottom: _animation.value, left: 0.0, right: 0.0, child: child)
            ],
          ),
        );
      },
      child: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.title), title: Text("home")),
          BottomNavigationBarItem(icon: Icon(Icons.title), title: Text("home")),
          BottomNavigationBarItem(icon: Icon(Icons.title), title: Text("home")),
          BottomNavigationBarItem(icon: Icon(Icons.title), title: Text("home")),
        ],
        type: BottomNavigationBarType.fixed,
      ),
    );
  }

  Widget _buildListView() => ListView.builder(
      controller: _scrollController,
      itemBuilder: (context, index) => ListTile(
            leading: Icon(Icons.access_alarm),
            title: Text("this is index: $index"),
          ));

}

home: AudioScreen(), //Countdown is temporarily hard to write and incomprehensible (official demo needs to follow up to see how it is written cleverly)

import 'dart:async';

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

class AudioScreen extends StatefulWidget {
  @override
  _AudioScreenState createState() => _AudioScreenState();
}

class _AudioScreenState extends State<AudioScreen> {
  Stopwatch stopwatch = Stopwatch();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.orangeAccent.withOpacity(0.2),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _buildRecordingStatus(),
            _buildTimerText(),
            _buildButtonRow(context),
          ],
        ),
      ),
    );
  }

  void _stopButtonPressed() {
    setState(() {
      stopwatch
        ..stop()
        ..reset();
    });
  }

  void _rightButtonPressed() {
    setState(() {
      if (stopwatch.isRunning) {
        stopwatch.stop();
      } else {
        stopwatch.start();
      }
    });
  }

  Widget _buildTimerText() {
    return Container(
        height: 200.0,
        child: Center(
          child: TimerText(stopwatch: stopwatch),
        ));
  }

  Widget _buildRecordingStatus() {
    return Container(
        height: 100.0,
        width: 100.0,
        child: stopwatch.isRunning
            ? Center(
                child: SpinKitWave(
                    color: Colors.black87.withOpacity(0.7),
                    type: SpinKitWaveType.start),
              )
            : Image.asset("assets/recorder.png"));
  }

  Widget _buildButtonRow(BuildContext context) {
    return Row(children: <Widget>[
      _buildButton(_stopButtonPressed, Colors.redAccent, context, Icons.stop),
      _buildButton(_rightButtonPressed, Colors.blueAccent, context,
          stopwatch.isRunning ? Icons.pause : Icons.play_arrow),
    ]);
  }

  Widget _buildButton(
      VoidCallback callback, Color color, BuildContext context, IconData icon) {
    Size size = MediaQuery.of(context).size;
    return Container(
        width: size.width * 0.5,
        alignment: Alignment.center,
        child: RaisedButton(
          elevation: 0.0,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(36.0)),
          color: color,
          onPressed: callback,
          child: Container(
            width: size.width * 0.5 - 80.0,
            height: MediaQuery.of(context).size.width * 0.15,
            child: Icon(
              icon,
              color: Colors.white,
              size: 32.0,
            ),
          ),
        ));
  }
}

class TimerText extends StatefulWidget {
  TimerText({this.stopwatch});
  final Stopwatch stopwatch;

  TimerTextState createState() => TimerTextState(stopwatch: stopwatch);
}

class TimerTextState extends State<TimerText> {
  Timer timer;
  final Stopwatch stopwatch;

  TimerTextState({this.stopwatch}) {
    timer = Timer.periodic(Duration(milliseconds: 30), callback);
  }

  void callback(Timer timer) {
    if (stopwatch.isRunning) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    final double width = MediaQuery.of(context).size.width;
    final TextStyle timerTextStyle = const TextStyle(
      fontSize: 60.0,
      fontFamily: "Open Sans",
      fontWeight: FontWeight.w300,
      color: Colors.black87,
    );
    List<String> formattedTime =
        TimerTextFormatter.format(stopwatch.elapsedMilliseconds);
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Container(
          child: Text(
            "${formattedTime[0]}:",
            style: timerTextStyle,
          ),
          width: width / 4.0,
        ),
        Container(
          child: Text(
            "${formattedTime[1]}:",
            style: timerTextStyle,
          ),
          width: width / 4.1,
        ),
        Container(
          child: Text(
            "${formattedTime[2]}",
            style: timerTextStyle,
          ),
          width: width / 4.6,
        ),
      ],
    );
  }
}

class TimerTextFormatter {
  static List<String> format(int milliseconds) {
    int hundreds = (milliseconds / 10).truncate();
    int seconds = (hundreds / 100).truncate();
    int minutes = (seconds / 60).truncate();

    String minutesStr = (minutes % 60).toString().padLeft(2, '0');
    String secondsStr = (seconds % 60).toString().padLeft(2, '0');
    String hundredsStr = (hundreds % 100).toString().padLeft(2, '0');

    return [minutesStr, secondsStr, hundredsStr];
//    return "$minutesStr:$secondsStr:$hundredsStr";
  }
}

home: ImScreen(),// IM Chat Note here that listview scrolling will be due to the increase of carton item. There is no good plan for this layout at present, look forward to the official.

import 'dart:async';

import 'package:flutter/material.dart';

class ImScreen extends StatefulWidget {
  @override
  _ImScreenState createState() => _ImScreenState();
}

class _ImScreenState extends State<ImScreen> {
  StreamController _messageController;
  TextEditingController _textController;
  List _myMessages;
  final _myName = "Vadaski";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _messageController = StreamController();
    _textController = TextEditingController();
    _myMessages = List();
  }

  @override
  void dispose() {
    _textController.dispose();
    _messageController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('IM Challenge'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Flexible(
                child: ListView.builder(
                    reverse: true,
                    itemCount: _myMessages.length,
                    itemBuilder: (context, index) {
                      return _buildMessageWidget(_myMessages[index], context);
                    })),
            Divider(
              height: 1.0,
            ),
            _buildInputWidget(context),
          ],
        ),
      ),
    );
  }

  Widget _buildInputWidget(BuildContext context) {
    return SizedBox(
      child: Padding(
        padding: const EdgeInsets.only(left: 8.0, right: 8.0),
        child: Row(
          children: <Widget>[
            Flexible(
                child: TextField(
              decoration:
                  InputDecoration.collapsed(hintText: "Send your message"),
              controller: _textController,
              onChanged: onMessageChanged,
              onSubmitted: onMessageSubmit,
            )),
            Container(
              margin: const EdgeInsets.symmetric(horizontal: 4.0),
              child: StreamBuilder(
                initialData: "",
                stream: _messageController.stream,
                builder: (context, snapshot) {
                  return IconButton(
                    icon: Icon(
                      Icons.send,
                      color: snapshot.data == ""
                          ? Colors.grey
                          : Theme.of(context).accentColor,
                    ),
                    onPressed: () => onMessageSubmit(_textController.text),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }

  Widget _buildMessageWidget(String text, BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10.0),
      width: MediaQuery.of(context).size.width / 2,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SizedBox(
            width: MediaQuery.of(context).size.width / 4,
          ),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: <Widget>[
                Text(_myName, style: Theme.of(context).textTheme.subhead),
                Container(
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(12.0),
                      color: Colors.blue.withOpacity(0.2)),
                  margin: const EdgeInsets.only(top: 5.0),
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      text,
                      overflow: TextOverflow.fade,
                      softWrap: true,
                    ),
                  ),
                )
              ],
            ),
          ),
          Container(
            margin: const EdgeInsets.only(right: 16.0, left: 8.0),
            child: CircleAvatar(
              child: Text(_myName[0]),
            ),
          ),
        ],
      ),
    );
  }

  onMessageChanged(String message) {
    _messageController.sink.add(message);
  }

  onMessageSubmit(String message) {
    _textController.clear();
    if (message != "") {
      setState(() {
        _myMessages.insert(0, message);
      });
    }
    onMessageChanged("");
  }
}

    home: RotatingScreen(),//

import 'package:flutter/material.dart';

import '../widgets/rotating_bar.dart';

class RotatingScreen extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   final size = MediaQuery.of(context).size;

   return Scaffold(
       body: Stack(
     children: <Widget>[
       Positioned(
         left: size.width / 5,
         top: size.height / 3,
         child: RotatingBar(
           getBackCenter: true,
           dx: size.width / 5,
           dy: size.height / 3,
           style: Style.Touch,
           getAngle: (angle) {
             print(angle);
           },
         ),
       )
     ],
   ));
 }
}

home: ScrollBackToTop(), //Scroll to the top is a common one

import 'package:flutter/material.dart';

class ScrollBackToTop extends StatefulWidget {
 @override
 _ScrollBackToTopState createState() => _ScrollBackToTopState();
}

class _ScrollBackToTopState extends State<ScrollBackToTop>
   with SingleTickerProviderStateMixin {
 ScrollController _controller;

 @override
 void initState() {
   super.initState();
   _controller = ScrollController();
 }

 @override
 void dispose() {
   _controller.dispose();
   super.dispose();
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text('Scroll Back To Top Demo'),
       centerTitle: true,
     ),
     body: ListView.builder(
         controller: _controller,
         itemCount: 100,
         itemBuilder: (context, index) {
           return ListTile(
             title: Center(
                 child: Text(
               'This is no $index',
               style: TextStyle(fontSize: 24),
             )),
           );
         }),
     floatingActionButton: FloatingActionButton(
       onPressed: backToTop,
       child: Icon(Icons.vertical_align_top),
     ),
   );
 }

 backToTop() {
   if (_controller.offset != 0)
     _controller.animateTo(
       0,
       duration: Duration(milliseconds: 500),
       curve: Curves.easeIn,
     );
 }
}

5.animation_demo (summarizes the various currently available scene animations github: https://github.com/geeklx/flutter_app2/tree/master/app2/animation_demo): Address attached due to limited code 

6.beaytiful_search_bar_demo (search bar): https://github.com/geeklx/flutter_app2/tree/master/app2/beaytiful_search_bar_demo

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

class SearchBarDemo extends StatefulWidget {
 @override
 _SearchBarDemoState createState() => _SearchBarDemoState();
}

class _SearchBarDemoState extends State<SearchBarDemo> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text('SearchBarDemo'),
       actions: <Widget>[
         IconButton(
             icon: Icon(Icons.search),
             onPressed: () =>
                 showSearch(context: context, delegate: SearchBarDelegate())),
       ],
     ),
   );
 }
}

const searchList = [
 "ChengDu",
 "ShangHai",
 "BeiJing",
 "TianJing",
 "NanJing",
 "ShenZheng"
];

const recentSuggest = [
 "suggest1",
 "suggest2"
];

class SearchBarDelegate extends SearchDelegate<String> {
 @override
 List<Widget> buildActions(BuildContext context) {
   return [IconButton(icon: Icon(Icons.clear), onPressed: () => query = "")];
 }

 @override
 Widget buildLeading(BuildContext context) {
   return IconButton(
       icon: AnimatedIcon(
           icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
       onPressed: () => close(context, null));
 }

 @override
 Widget buildResults(BuildContext context) {
   return Center(child: Container(
     width: 100.0,
     height: 100.0,
     child: Card(
       color: Colors.redAccent,
       child: Center(
         child: Text(query),
       ),
     ),
   ),);
 }

 @override
 Widget buildSuggestions(BuildContext context) {
   final suggestionList = query.isEmpty
       ? recentSuggest
       : searchList.where((input) => input.startsWith(query)).toList();
   return ListView.builder(
       itemCount: suggestionList.length,
       itemBuilder: (context, index) => ListTile(

         onTap: (){
           query = suggestionList[index];
           showResults(context);},

             title: RichText(
                 text: TextSpan(
                     text: suggestionList[index].substring(0, query.length),
                     style: TextStyle(
                         color: Colors.black, fontWeight: FontWeight.bold),
                     children: [
                   TextSpan(
                       text: suggestionList[index].substring(query.length),
                       style: TextStyle(color: Colors.grey))
                 ])),
           ));
 }
}

7.bloc_provider_pattern (listening for private method call writing): https://github.com/geeklx/flutter_app2/tree/master/app2/bloc_provider_pattern

import 'dart:async';

import './bloc_base.dart';

class IncrementBloc implements BlocBase {
 int _counter;

 StreamController<int> _counterPipe = StreamController<int>();
 Stream<int> get outCounter => _counterPipe.stream;

 IncrementBloc() {
   _counter = 0;
   //_counterPipe for StreamBuilder, has automatically added listen
 }

 incrementCounter() {
   _counter = _counter + 1;
   _counterPipe.sink.add(_counter);
 }

 void dispose() {
   print('bloc disposed!');
   _counterPipe.close();
 }
}


import 'package:flutter/material.dart';

// Generic Interface for all BLoCs
abstract class BlocBase {
 void dispose();
}

// Generic BLoC provider
class BlocProvider<T extends BlocBase> extends StatefulWidget {
 BlocProvider({
   Key key,
   @required this.child,
   @required this.bloc,
 }) : super(key: key);

 final T bloc;
 final Widget child;

 @override
 _BlocProviderState<T> createState() => _BlocProviderState<T>();

 static T of<T extends BlocBase>(BuildContext context) {
   final type = _typeOf<BlocProvider<T>>();
   BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
   return provider.bloc;
 }

 static Type _typeOf<T>() => T;
}

class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
 @override
 void dispose() {
   widget.bloc.dispose();
   super.dispose();
 }

 @override
 Widget build(BuildContext context) {
   return widget.child;
 }
}
//EOP

8.bottom_appbar_demo (common base notation for bottom navigation): https://github.com/geeklx/flutter_app2/tree/master/app2/bottom_appbar_demo

import 'package:flutter/material.dart';

class EachView extends StatefulWidget {
 String _title;
 EachView(this._title);
 @override
 _EachViewState createState() => _EachViewState();
}

class _EachViewState extends State<EachView> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(title: Text(widget._title),),
   );
 }
}

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

class BottomAppBarDemo extends StatefulWidget {
 @override
 _BottomAppBarDemoState createState() => _BottomAppBarDemoState();
}

class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
 List<Widget> _eachView;
 int _index = 0;

 @override
 void initState() {
   // TODO: implement initState
   super.initState();
   _eachView = List();
   _eachView..add(EachView('home'))..add(EachView('me'));
 }

 @override
 Widget build(BuildContext context) {
   return new Scaffold(
     body: _eachView[_index],
     floatingActionButton: new FloatingActionButton(
       onPressed: () {
         Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context){
           return EachView('New Page');
         }));
       },
       tooltip: 'Increment',
       child: new Icon(Icons.add),
     ), // T
     floatingActionButtonLocation:
         FloatingActionButtonLocation.centerDocked, // his
     bottomNavigationBar: BottomAppBar(
       color: Colors.lightBlue,
       shape: CircularNotchedRectangle(),
       child: Row(
         mainAxisSize: MainAxisSize.max,
         mainAxisAlignment: MainAxisAlignment.spaceAround,
         children: <Widget>[
           IconButton(
             icon: Icon(Icons.near_me),
             color: Colors.white,
             onPressed: () {
               setState(() {
                 _index = 0;
               });
             },
           ),
           IconButton(
             icon: Icon(Icons.edit_location),
             color: Colors.white,
             onPressed: () {
               setState(() {
                 _index = 1;
               });
             },
           ),
         ],
       ),
     ),
   );
 }
}

9.chip_demo: https://github.com/geeklx/flutter_app2/tree/master/app2/chip_demo

import 'package:chip_demo/input_chip.dart';
/**
* Please view them separately by switching home's comment
*/
import 'package:flutter/material.dart';

import 'choice_chip.dart';

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

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return new MaterialApp(
     title: 'Flutter Demo',
     theme: new ThemeData.light(),
//      home: ChipDemo(),
//      home: ActionChipDemo(),
// home: FilterChipDemo(), //Check Status
// home: ChoiceChipDemo(), //Selected State Common
     home: InputChipDemo(),
   );
 }
}

10.custom_router_transition (standard routing notation): https://github.com/geeklx/flutter_app2/tree/master/app2/custom_router_transition

/**
* Navigator.of(context).push Custom route
*/
import 'package:flutter/material.dart';
import 'custome_router.dart';

class FirstPage extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     backgroundColor: Colors.blue,
     appBar: AppBar(
       title: Text(
         'FirstPage',
         style: TextStyle(fontSize: 36.0),
       ),
       elevation: 0.0,
     ),
     body: Center(
       child: MaterialButton(
           child: Icon(
             Icons.navigate_next,
             color: Colors.white,
             size: 64.0,
           ),
           onPressed: () =>
               Navigator.of(context).push(
                   CustomRoute(SecondPage()))),
     ),
   );
 }
}

class SecondPage extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     backgroundColor: Colors.pinkAccent,
     appBar: AppBar(
       title: Text('SecondPage',style: TextStyle(fontSize: 36.0),),
       backgroundColor: Colors.pinkAccent,
       leading: Container(),
       elevation: 0.0,
     ),
     body: Center(
       child: MaterialButton(
           child: Icon(
             Icons.navigate_before,
             color: Colors.white,
             size: 64.0,
           ),
           onPressed: () => Navigator.of(context).pop()),
     ),
   );
 }
}


Provide several overanimations
/**
* Routing transition animation through custom transitionsBuilder
*
* Please switch between different comments to view separately
*/
import 'package:flutter/material.dart';

class CustomRoute extends PageRouteBuilder {
 final Widget widget;
 CustomRoute(this.widget)
     : super(
         transitionDuration: const Duration(seconds: 2),
         pageBuilder: (BuildContext context, Animation<double> animation,
             Animation<double> secondaryAnimation) {
           return widget;
         },
         transitionsBuilder: (BuildContext context,
             Animation<double> animation,
             Animation<double> secondaryAnimation,
             Widget child) {
           //Fade Out Transition Routing
         return FadeTransition(
             opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
                 parent: animation, curve: Curves.fastOutSlowIn)),
             child: child,
             );

           //Scale Conversion Routing
//          return ScaleTransition(
//            scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
//                parent: animation, curve: Curves.fastOutSlowIn)),
//            child: child,
//            );

           //Rotate+Scale Conversion Routing
//            return RotationTransition(
//              turns: Tween(begin: -1.0, end: 1.0).animate(CurvedAnimation(
//                  parent: animation, curve: Curves.fastOutSlowIn)),
//              child: ScaleTransition(
//                scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
//                    parent: animation, curve: Curves.fastOutSlowIn)),
//                child: child,
//              ),
//            );

           //Slide Routing
//            return SlideTransition(
//              position:
//                  Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset(0.0, 0.0))
//                      .animate(CurvedAnimation(
//                          parent: animation, curve: Curves.fastOutSlowIn)),
//              child: child,
//            );
         },
       );
}

11.event_bus_demo (local refresh of page data using event bus synchronization is common): https://github.com/geeklx/flutter_app2/tree/master/app2/event_bus_demo

import 'package:flutter/material.dart';
import 'tools/bus.dart';
import 'events/count_events.dart';
import 'sceeens/first_screen.dart';

void main(){
 runApp(App());
 behaviorBus.fire(CountEvent(0));
}

class App extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter Demo',
     theme: ThemeData.dark(),
     home: FirstScreen(),

   );
 }
}

Is too laggy to follow up at present: https://github.com/geeklx/flutter_app2/tree/master/app2/expansion_demo

1.
/**
 *The most basic expansion widget tile
 * The usage is simple, just place the parts that need to be expanded in children
 * Other uses are similar to list tile s
 * When expansion tile is expanded, we can see background color
 * A transition animation is performed to transition
 * expansion tile There is also a trailing attribute, which represents the small arrow on the right
 * Replaceable
 * initiallyExpanded Represents whether the initial state is expanded
 * Default to false, that is, do not expand
 *
 * When there are multiple expansion tile s in a list view
 * Each expansion tile needs to be assigned a unique [PageStorageKey]
 * To keep the expansion tile on and off during sliding
 */

import 'package:flutter/material.dart';

class ExpansionTileDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('expansion tile demo'),),
      body: Center(
        child: ExpansionTile(
            title: Text('Expansion Tile'),
            leading: Icon(Icons.ac_unit),
            backgroundColor: Colors.white12,
            children: <Widget>[
              ListTile(
                title: Text('list tile'),
                subtitle: Text('subtitle'),
              ),
            ],
//          initiallyExpanded: true,
        ),
      ),
    );
  }
}

2.
/**
 *  To be honest, I don't think the expansion panel list is at all useful
 *  So I don't want to comment.
 *  Here the sample code is from the flutter developer
 *  He will often update some flutter tutorials, which are well written and interesting to see for himself
 *  https://mp.weixin.qq.com/s/Qv08V42LgEr8IATUSfVVHg
 *
 *  A few points to note:
 *  ExpansionPanelList Must be used in slidable components
 *  ExpansionPanel Can only be used in ExpansionPanelList
 *  In addition to ExpansionPanel, there is a special ExpansionPanelRadio
 *  Also available only in ExpansionPanelList
 */

import 'package:flutter/material.dart';

class ExpansionPanelListDemo extends StatefulWidget {
  @override
  _ExpansionPanelListDemoState createState() => _ExpansionPanelListDemoState();
}

class _ExpansionPanelListDemoState extends State<ExpansionPanelListDemo> {
  var currentPanelIndex = -1;

  List<int> mList;
  //Used to save the state of the expansionPanel
  List<ExpandStateBean> expandStateList;

  _ExpansionPanelListDemoState() {
    mList = new List();
    expandStateList = new List();
    for (int i = 0; i < 10; i++) {
      mList.add(i);
      expandStateList.add(ExpandStateBean(i, false));
    }
  }

  _setCurrentIndex(int index, isExpand) {
    setState(() {
      expandStateList.forEach((item) {
        if (item.index == index) {
          item.isOpen = !isExpand;
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("expansion panel list"),
        ),
        body: SingleChildScrollView(
          child: ExpansionPanelList(
            expansionCallback: (index, bol) {
              _setCurrentIndex(index, bol);
            },
            children: mList.map((index) {
              return new ExpansionPanel(
                headerBuilder: (context, isExpanded) {
                  return new ListTile(
                    title: new Text('This is NO. $index'),
                  );
                },
                body: ListTile(
                  title: Text('expansion no.$index'),
                ),
                isExpanded: expandStateList[index].isOpen,
              );
            }).toList(),
          ),
        ));
  }
}

class ExpandStateBean {
  var isOpen;
  var index;
  ExpandStateBean(this.index, this.isOpen);
}

13.flutter_bottomnavigationbar (bottom navigation standard spelling support survival): https://github.com/geeklx/flutter_app2/tree/master/app2/flutter_bottomnavigationbar

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

class AirPlayScreen extends StatefulWidget {
  @override
  _AirPlayScreenState createState() => _AirPlayScreenState();
}

class _AirPlayScreenState extends State<AirPlayScreen>
    with AutomaticKeepAliveClientMixin {
  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;

  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AirPlayScreen'),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

2.
import 'package:flutter/material.dart';
import 'package:flutter_bottomnavigationbar/pages_keep_alive/airplay_screen.dart';
import 'package:flutter_bottomnavigationbar/pages_keep_alive/email_screen.dart';
import 'package:flutter_bottomnavigationbar/pages_keep_alive/home_screen.dart';
import 'package:flutter_bottomnavigationbar/pages_keep_alive/pages_screen.dart';

class NavigationKeepAlive extends StatefulWidget {
  @override
  _NavigationKeepAliveState createState() => _NavigationKeepAliveState();
}

class _NavigationKeepAliveState extends State<NavigationKeepAlive>
    with SingleTickerProviderStateMixin {

  final _bottomNavigationColor = Colors.blue;
  int _currentIndex = 0;
  var _controller = PageController(
    initialPage: 0,
  );

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _controller,
        children: <Widget>[
          AirPlayScreen(),
          EmailScreen(),
          HomeScreen(),
          PagesScreen()
        ],
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
//          onTap: (index)=> _controller.animateToPage(index, duration: Duration(milliseconds: 500), curve: Curves.fastOutSlowIn),
        onTap: (index) {
          _controller.jumpToPage(index);
          setState(() {
            _currentIndex = index;
          });
        },
        type: BottomNavigationBarType.fixed,
        items: [
          BottomNavigationBarItem(
              icon: Icon(
                Icons.home,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'HOME',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.email,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'Email',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.pages,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'PAGES',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.airplay,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'AIRPLAY',
                style: TextStyle(color: _bottomNavigationColor),
              )),
        ],
      ),
    );
  }
}

3.
/**
 * New implementation using pageview: navigation - keep - alive
 * This way, AutomaticKeepAliveClientMixin can be implemented through a subpage state
 * To achieve the effect of switching pages to keep state.
 * Please switch the home comment to view separately
 */
import 'package:flutter/material.dart';
import 'bottom_navigation_widget.dart';

import 'navigation_keep_alive.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter bottomNavigationBar',
      theme: new ThemeData.dark(),
//      home: BottomNavigationWidget(),
    home: NavigationKeepAlive(),
    );
  }
}

14.flutter_provide (official notation does not use eventbus for data synchronization refresh sharing): https://github.com/geeklx/flutter_app2/tree/master/app2/flutter_provide

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

class Counter with ChangeNotifier{
  int value = 0;

  increment(){
    value++;
    notifyListeners();
  }
}
2.
import 'package:flutter/material.dart';

class Switcher with ChangeNotifier{
  bool status = false;

  changeStatus(){
    status = !status;
    notifyListeners();
  }
}
3.
import 'package:flutter/material.dart';
import 'package:provide/provide.dart';

import 'models/counter.dart';
import 'models/switcher.dart';
import 'second_screen.dart';

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            Provide<Counter>(
              builder: (context, child, counter) {
                return Text(
                  '${counter.value}',
                  style: Theme.of(context).textTheme.display1,
                );
              },
            ),
            Provide<Switcher>(
              builder: (context, child, switcher) {
                return Switch(
                    value: switcher.status,
                    onChanged: (newValue) {
                      switcher.changeStatus();
                    });
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context)
              .push(MaterialPageRoute(builder: (context) => SecondScreen()));
        },
        child: Icon(Icons.navigate_next),
      ),
    );
  }
}
4.
import 'package:flutter/material.dart';
import 'package:provide/provide.dart';
import 'models/counter.dart';
import 'models/switcher.dart';

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            Provide<Counter>(
              builder: (context, child, counter) {
                return Text(
                  '${counter.value}',
                  style: Theme.of(context).textTheme.display1,
                );
              },
            ),
            Provide<Switcher>(
              builder: (context, child, switcher) {
                return Switch(
                    value: switcher.status,
                    onChanged: (newValue) {
                      switcher.changeStatus();
                    });
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provide.value<Counter>(context).increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

15.flutter_widget_of_the_week (custom control section): https://github.com/geeklx/flutter_app2/tree/master/app2/flutter_widget_of_the_week

16.frosted_glass_style_demo (frosted glass effect): https://github.com/geeklx/flutter_app2/tree/master/app2/frosted_glass_style_demo

/**
* Frosted glass effect with BackdropFilter and Opacity needs to be set on the sub-parts
* This part is expensive and should be used as sparingly as possible
* The sigmaX/Y of ImageFilter.blur determines the fuzziness of the frosted glass, the higher the value, the fuzzier
* Generally speaking, ClipRect Widget wrapping is required to prevent blurring of boundaries
 */
import 'package:flutter/material.dart';
import 'dart:ui';

class FrostedGlassDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Stack(
        children: <Widget>[
          new ConstrainedBox(
              constraints: const BoxConstraints.expand(),
              child: new FlutterLogo()),
          new Center(
            child: new ClipRect(
              child: new BackdropFilter(
                filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
                child: Opacity(
                  opacity: 0.5,
                  child: new Container(
                    width: 200.0,
                    height: 200.0,
                  decoration: new BoxDecoration(
//                  color: Colors.grey.shade200.withOpacity(0.5),
                  color: Colors.grey.shade200,
                  ),
                    child: new Center(
                      child: new Text('Frosted',
                          style: Theme.of(context).textTheme.display3),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

17.hero_demo (Official standard follow animation doesn't feel much use right now): https://github.com/geeklx/flutter_app2/tree/master/app2/hero_demo

 

1.
/**
 * When HeroAnimation is provided as the home property of the app,
 * MaterialApp The starting path is implicitly pushed.
 * InkWell Packaging images makes it easy to add tapping gestures to source and target heroes.
 * Defining the Material widget with a transparent color "pops up" the background of the image as it flies to the target.
 * SizedBox Specifies the size of the hero at the beginning and end of the animation.
 * Setting the fit property of the image to BoxFit.contain ensures that the image is as large as possible during the transition.
 * It will not change its aspect ratio.
 */
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;

class SourceHeroPage extends StatelessWidget {
  Widget build(BuildContext context) {
    timeDilation = 5.0; // 1.0 means normal animation speed.

    return Scaffold(
      appBar: AppBar(
        title: const Text('Basic Hero Animation'),
      ),
      body: Center(
        child: PhotoHero(
          photo: 'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
          width: 300.0,
          onTap: () {
            Navigator.of(context).push(MaterialPageRoute<Null>(
                builder: (BuildContext context) => DestinationHeroPage()));
          },
        ),
      ),
    );
  }
}

class DestinationHeroPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flippers Page'),
      ),
      body: Container(
        // The blue background emphasizes that it's a new route.
        color: Colors.lightBlueAccent,
        padding: const EdgeInsets.all(16.0),
        alignment: Alignment.topLeft,
        child: PhotoHero(
          photo: 'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
          width: 100.0,
          onTap: () {
            Navigator.of(context).pop();
          },
        ),
      ),
    );
  }
}

class PhotoHero extends StatelessWidget {
  const PhotoHero({Key key, this.photo, this.onTap, this.width})
      : super(key: key);

  final String photo;
  final VoidCallback onTap;
  final double width;

  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      child: Hero(
        tag: photo,
        child: Material(
          color: Colors.transparent,
          child: InkWell(
            onTap: onTap,
            child: Image.network(
              photo,
              fit: BoxFit.contain,
            ),
          ),
        ),
      ),
    );
  }
}

2.
/**
 * When HeroAnimation is provided as the home property of the app,
 * MaterialApp The starting path is implicitly pushed.
 * InkWell Packaging images makes it easy to add tapping gestures to source and target heroes.
 * Defining the Material widget with a transparent color "pops up" the background of the image as it flies to the target.
 * SizedBox Specifies the size of the hero at the beginning and end of the animation.
 * Setting the fit property of the image to BoxFit.contain ensures that the image is as large as possible during the transition.
 * It will not change its aspect ratio.
 */
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;

class SourceHeroPage extends StatelessWidget {
  Widget build(BuildContext context) {
    timeDilation = 5.0; // 1.0 means normal animation speed.

    return Scaffold(
      appBar: AppBar(
        title: const Text('Basic Hero Animation'),
      ),
      body: Center(
        child: PhotoHero(
          photo: 'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
          width: 300.0,
          onTap: () {
            Navigator.of(context).push(MaterialPageRoute<Null>(
                builder: (BuildContext context) => DestinationHeroPage()));
          },
        ),
      ),
    );
  }
}

class DestinationHeroPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flippers Page'),
      ),
      body: Container(
        // The blue background emphasizes that it's a new route.
        color: Colors.lightBlueAccent,
        padding: const EdgeInsets.all(16.0),
        alignment: Alignment.topLeft,
        child: PhotoHero(
          photo: 'http://pic1.win4000.com/wallpaper/e/537ebd9b60603.jpg',
          width: 100.0,
          onTap: () {
            Navigator.of(context).pop();
          },
        ),
      ),
    );
  }
}

class PhotoHero extends StatelessWidget {
  const PhotoHero({Key key, this.photo, this.onTap, this.width})
      : super(key: key);

  final String photo;
  final VoidCallback onTap;
  final double width;

  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      child: Hero(
        tag: photo,
        child: Material(
          color: Colors.transparent,
          child: InkWell(
            onTap: onTap,
            child: Image.network(
              photo,
              fit: BoxFit.contain,
            ),
          ),
        ),
      ),
    );
  }
}

18.intro_views (this is a good standard welcome page template found so far for your reference): https://github.com/geeklx/flutter_app2/tree/master/app2/intro_views

  

1.
import 'package:flutter/material.dart';
import 'package:intro_views_flutter/Models/page_view_model.dart';
import 'package:intro_views_flutter/intro_views_flutter.dart';

import 'home_page.dart';

class IntroViewDemo extends StatelessWidget {
  //making list of pages needed to pass in IntroViewsFlutter constructor.
  final pages = [
    new PageViewModel(
        pageColor: const Color(0xFF03A9F4),
        iconImageAssetPath: 'assets/air-hostess.png',
        iconColor: null,
        bubbleBackgroundColor: null,
        body: Text(
          'Haselfree  booking  of  flight  tickets  with  full  refund  on  cancelation',
        ),
        title: Text(
          'Flights',
        ),
        textStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white),
        mainImage: Image.asset(
          'assets/airplane.png',
          height: 285.0,
          width: 285.0,
          alignment: Alignment.center,
        )),
    new PageViewModel(
      pageColor: const Color(0xFF8BC34A),
      iconImageAssetPath: 'assets/waiter.png',
      iconColor: null,
      bubbleBackgroundColor: null,
      body: Text(
        'We  work  for  the  comfort ,  enjoy  your  stay  at  our  beautiful  hotels',
      ),
      title: Text('Hotels'),
      mainImage: Image.asset(
        'assets/hotel.png',
        height: 285.0,
        width: 285.0,
        alignment: Alignment.center,
      ),
      textStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white),
    ),
    new PageViewModel(
      pageColor: const Color(0xFF607D8B),
      iconImageAssetPath: 'assets/taxi-driver.png',
      iconColor: null,
      bubbleBackgroundColor: null,
      body: Text(
        'Easy  cab  booking  at  your  doorstep  with  cashless  payment  system',
      ),
      title: Text('Cabs'),
      mainImage: Image.asset(
        'assets/taxi.png',
        height: 285.0,
        width: 285.0,
        alignment: Alignment.center,
      ),
      textStyle: TextStyle(fontFamily: 'MyFont', color: Colors.white),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'IntroViews Flutter', //title of app
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ), //ThemeData
      home: new Builder(
        builder: (context) => new IntroViewsFlutter(
              pages,
              onTapDoneButton: () {
                Navigator.push(
                  context,
                  new MaterialPageRoute(
                    builder: (context) =>
                        new MyHomePage(title: 'Flutter Demo Home Page'),
                  ), //MaterialPageRoute
                );
              },
              showSkipButton:
                  true, //Whether you want to show the skip button or not.
              pageButtonTextStyles: TextStyle(
                color: Colors.white,
                fontSize: 18.0,
              ),
            ), //IntroViewsFlutter
      ), //Builder
    ); //Material App
  }
}

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

19.keep_alive_demo (similar to fragment information stored in the same activity): https://github.com/geeklx/flutter_app2/tree/master/app2/keep_alive_demo

1.
import 'package:flutter/material.dart';
import 'package:keep_alive_demo/keep_alive_demo.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: KeepAliveDemo(),
    );
  }
}

class KeepAliveDemo extends StatefulWidget {
  @override
  _KeepAliveDemoState createState() => _KeepAliveDemoState();
}

class _KeepAliveDemoState extends State<KeepAliveDemo>
    with SingleTickerProviderStateMixin {
  TabController _controller;
  final _bottomNavigationColor = Colors.blue;
  int _currentIndex = 0;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller = TabController(length: 3, vsync: this);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _controller,
          tabs: [
            Tab(icon: Icon(Icons.directions_car)),
            Tab(icon: Icon(Icons.directions_transit)),
            Tab(icon: Icon(Icons.directions_bike)),
          ],
        ),
        title: Text('Keep Alive Demo'),
      ),
      body: TabBarView(
        controller: _controller,
        children: [
          MyHomePage(
            title: 'Keep Alive demo',
          ),
          MyHomePage(
            title: 'Keep Alive demo',
          ),
          MyHomePage(
            title: 'Keep Alive demo',
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: Icon(
                Icons.home,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'HOME',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.email,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'Email',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.pages,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'PAGES',
                style: TextStyle(color: _bottomNavigationColor),
              )),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.airplay,
                color: _bottomNavigationColor,
              ),
              title: Text(
                'AIRPLAY',
                style: TextStyle(color: _bottomNavigationColor),
              )),
        ],
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

2.
import 'package:flutter/material.dart';
/**
 * Implementation principle, use AutomaticKeepAliveClientMixin, and override the wantKeepAlive method so that the state is not recycled.
 */

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with AutomaticKeepAliveClientMixin{
  int _counter = 0;

  // TODO: implement wantKeepAlive
  @override
  bool get wantKeepAlive => true;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }


}

20.load_multi_image (picture upload with multiple selections, the current problem is that the list shows that the small image is not clear enough to think of a solution): https://github.com/geeklx/flutter_app2/tree/master/app2/load_multi_image

 

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:multi_image_picker/asset.dart';
import 'package:multi_image_picker/multi_image_picker.dart';

class LoadImageDemo extends StatefulWidget {
  @override
  _LoadImageDemoState createState() => _LoadImageDemoState();
}

class _LoadImageDemoState extends State<LoadImageDemo> {
  List<Asset> images = List<Asset>();
  String _error;

  Future<void> loadAssets() async {
    setState(() {
      images = List<Asset>();
    });
    List resultList;
    try {
      resultList = await MultiImagePicker.pickImages(
        maxImages: 300,
      );
    } on PlatformException catch (e) {
      _error = e.message;
    }
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      images = resultList;
      if (_error == null) _error = 'No Error Dectected';
    });
  }

  Widget builtImage(Asset asset) {
    if (asset.thumbData != null) {
      return Image.memory(
        asset.thumbData.buffer.asUint8List(),
        fit: BoxFit.cover,
        gaplessPlayback: true,
      );
    }
    return Container();
  }

  void _loadImage(Asset asset) async {
    await asset.requestThumbnail(300, 300);
//    await asset.releaseThumb();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('LoadImageDemo'),
      ),
      body: ListView.builder(
          itemCount: images.length,
          itemBuilder: (context, index) {
            _loadImage(images[index]);
            return builtImage(images[index]);
          }),
      floatingActionButton: FloatingActionButton(
        onPressed: loadAssets,
        child: Icon(Icons.image),
      ),
    );
  }
}

21.overlay (the overlay component enables us to cover a new layer of components at the top of the current page): https://github.com/geeklx/flutter_app2/tree/master/app2/overlay

/**
 * Please switch the comments in import to view separately
 */
import 'package:flutter/material.dart';
//import 'overlay_demo.dart';
//import 'overlay_demo2.dart';
import 'overlay_demo3.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: OverlayDemo(),
    );
  }
}

22.pinch_zoom_image_demo (nice third-party picture loading with cache mechanism): https://github.com/geeklx/flutter_app2/tree/master/app2/pinch_zoom_image_demo

import 'package:flutter/material.dart';
import 'package:pinch_zoom_image/pinch_zoom_image.dart';
import 'package:cached_network_image/cached_network_image.dart';

class PinchZoomImageDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pinch Zoom Image Demo'),
      ),
      body: ListView(
        children: <Widget>[
          PinchZoomImage(
            image: Image.network('https://s2.51cto.com/wyfs02/M01/89/BA/wKioL1ga-u7QnnVnAAAfrCiGnBQ946_middle.jpg'),
            zoomedBackgroundColor: Color.fromRGBO(240, 240, 240, 1.0),
          ),
          PinchZoomImage(
            image: Image(
              image:
                  CachedNetworkImageProvider(
                      'https://s2.51cto.com/wyfs02/M01/89/BA/wKioL1ga-u7QnnVnAAAfrCiGnBQ946_middle.jpg',
                  ),
            ),
            zoomedBackgroundColor: Color.fromRGBO(240, 240, 240, 1.0),
          ),
        ],
      ),
    );
  }
}

23.pull_on_load (drop-down refresh is standard): https://github.com/geeklx/flutter_app2/tree/master/app2/pull_on_load

24.redux_demo (demo is a good example of standard framework usage for page passing): https://github.com/geeklx/flutter_app2/tree/master/app2/redux_demo

 

1.
import 'package:meta/meta.dart';

/**
 * State All properties in should be read-only
 */
@immutable
class CountState {
  final int _count;
  get count => _count;

  CountState(this._count);

  CountState.initState() : _count = 0;
}

/**
 * Define all actions that operate on this State
 * There's only one action to add count here
 */
enum Action { increment }

/**
 * reducer A new CountState will be generated from the incoming action
 */
CountState reducer(CountState state, action) {
  //Match Action
  if (action == Action.increment) {
    return CountState(state.count + 1);
  }
  return state;
}

2.
import 'package:flutter/material.dart';
import 'package:redux_demo/under_screen.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux_demo/states/count_state.dart';

class TopScreen extends StatefulWidget {
  @override
  _TopScreenState createState() => _TopScreenState();
}

class _TopScreenState extends State<TopScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Top Screen'),
      ),
      body: Center(
        child: StoreConnector<CountState,int>(
          converter: (store) => store.state.count,
          builder: (context, count) {
            return Text(
              count.toString(),
              style: Theme.of(context).textTheme.display1,
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context){
            return UnderScreen();
          }));
        },
        child: Icon(Icons.forward),
      ),
    );
  }
}

3.
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux_demo/states/count_state.dart';

class UnderScreen extends StatefulWidget {
  @override
  _UnderScreenState createState() => _UnderScreenState();
}

class _UnderScreenState extends State<UnderScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Under Screen'),
      ),
      body: Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            StoreConnector<CountState,int>(
              converter: (store) => store.state.count,
              builder: (context, count) {
                return Text(
                  count.toString(),
                  style: Theme.of(context).textTheme.display1,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: StoreConnector<CountState,VoidCallback>(

        converter: (store) {
          return () => store.dispatch(Action.increment);
        },
        builder: (context, callback) {
          return FloatingActionButton(
            onPressed: callback,
            child: Icon(Icons.add),
          );
        },
      ),
    );
  }
}

Not finished yet...




Posted by Zpixel on Wed, 05 Jun 2019 09:25:06 -0700