Flutter

337 阅读9分钟

Gitee地址

创建flutter应用

fluter creat flutter_app

web启动服务

flutter run -d chrome

去除debuger bannber

 debugShowCheckedModeBanner: false,

Drawer

  • componets/drawer_containter.dart
import 'package:flutter/material.dart';

class DrawerContianer extends StatelessWidget {
  const DrawerContianer({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('Drawer Header'),
              ),
              ListTile(
                title: Text('Item 1'),
                onTap: () {
                },
              ),
              ListTile(
                title: Text('Item 2'),
                onTap: () {
                },
              ),
            ],
          ),
    );
  }
}
  • main.dart
import 'package:flutter/material.dart';
import './components/drawer_container.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primaryColor: Color.fromRGBO(37, 40, 47, 1),
        brightness: Brightness.dark,
      ),
      home: MyHomePage(title: '信号区'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;
  MyHomePage({Key key, this.title}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        endDrawer: DrawerContianer());
  }
}

设置路由

MaterialApp文档

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primaryColor: Color.fromRGBO(37, 40, 47, 1),
        brightness: Brightness.dark,
      ),
      initialRoute: '/',
      routes: {
         '/': (context) => MyHomePage(title: '信号区')
      },
    );
  }
}

目录拆分

image.png

components //放组件
pages //放页面

pages/home_page.dart

import 'package:flutter/material.dart';
import '../components/drawer_container.dart';
class MyHomePage extends StatelessWidget {
  final String title;
  MyHomePage({Key key, this.title}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        endDrawer: DrawerContianer());
  }
}

paegs/list_page.dart

import 'package:flutter/material.dart';
class ListPage extends StatelessWidget {
  const ListPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('ListPage'),
    );
  }
}

pages/login_page.dart

import 'package:flutter/material.dart';
class LoginPage extends StatelessWidget {
  const LoginPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('LoginPage'),
    );
  }
}

main.dart

import 'package:flutter/material.dart';
import './pages/home_page.dart';
import './pages/login_page.dart';
import './pages/list_page.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primaryColor: Color.fromRGBO(37, 40, 47, 1),
        brightness: Brightness.dark,
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => MyHomePage(title: '信号区'),
        '/login': (context) => LoginPage(),
        '/list': (context) => ListPage(),
      },
    );
  }
}


pubspec.yaml 设置本地图片目录

flutter:
  assets:
    - lib/assets/images/

pages/login_page.dart

import 'package:flutter/material.dart';

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('登录'),
        centerTitle: true,
      ),
      body: Theme(
        data: Theme.of(context).copyWith(
          primaryColor: Colors.orange,
        ),
        child: Container(
          padding: EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                  width: double.infinity,
                  child: Image.asset(
                    'lib/assets/images/header-illustration.png',
                  )),
              RegisterForm(),
            ],
          ),
        ),
      ),
    );
  }
}

class RegisterForm extends StatefulWidget {
  @override
  RegisterFormState createState() => RegisterFormState();
}

class RegisterFormState extends State<RegisterForm> {
  final registerFormKey = GlobalKey<FormState>();
  String username, password;
  bool autovalidate = false;

  void submitRegisterForm() {
    if (registerFormKey.currentState.validate()) {
      registerFormKey.currentState.save();

      debugPrint('username: $username');
      debugPrint('password: $password');

      Scaffold.of(context).showSnackBar(SnackBar(
        content: Text('Registering...'),
      ));
    } else {
      setState(() {
        autovalidate = true;
      });
    }
  }

  String validateUsername(value) {
    if (value.isEmpty) {
      return 'Username is required.';
    }

    return null;
  }

  String validatePassword(value) {
    if (value.isEmpty) {
      return 'Password is required.';
    }

    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: registerFormKey,
      child: Column(
        children: <Widget>[
          TextFormField(
            decoration: InputDecoration(
              labelText: '用户名',
              helperText: '',
            ),
            onSaved: (value) {
              username = value;
            },
            validator: validateUsername,
            autovalidate: autovalidate,
          ),
          TextFormField(
            obscureText: true,
            decoration: InputDecoration(
              labelText: '密码',
              helperText: '',
            ),
            onSaved: (value) {
              password = value;
            },
            validator: validatePassword,
            autovalidate: autovalidate,
          ),
          SizedBox(
            height: 32.0,
          ),
          Container(
            width: double.infinity,
            child: RaisedButton(
              child: Text('登录', style: TextStyle(color: Colors.white)),
              elevation: 0.0,
              onPressed: () {
                //  Navigator.pushNamed(context, '/');
                Navigator.of(context).pushNamed(
                  "/",
                  arguments: {'name': 'hikaru', 'age': 18},
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

image.png

底部菜单栏

git checkout -b toolbar

查看代码 image.png image.png

完善MinePage

git checkout -b pages

添加自定icon

dependencies:
  flutter:
    sdk: flutter
 iconfont_dart: ^0.3.3  //三方包
fonts:
    - family: iconfont
      fonts:
        - asset: lib/assets/fonts/iconfont.tt //引入自定义路径

lib/untils/Icon.dart

import 'package:flutter/material.dart';

Icon iconshoucang({double size = 18.0, Color color}) => Icon(
  IconData(0xe6d9, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconqueren({double size = 18.0, Color color}) => Icon(
  IconData(0xe8d8, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconjaifill({double size = 18.0, Color color}) => Icon(
  IconData(0xe6e0, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconjia({double size = 18.0, Color color}) => Icon(
  IconData(0xe6e1, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconjianfill({double size = 18.0, Color color}) => Icon(
  IconData(0xe712, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconjian({double size = 18.0, Color color}) => Icon(
  IconData(0xe713, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconhebingxingzhuang({double size = 18.0, Color color}) => Icon(
  IconData(0xe61c, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconsc({double size = 18.0, Color color}) => Icon(
  IconData(0xe61b, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconorder({double size = 18.0, Color color}) => Icon(
  IconData(0xe600, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconmine({double size = 18.0, Color color}) => Icon(
  IconData(0xe603, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconluckinCoffee({double size = 18.0, Color color}) => Icon(
  IconData(0xe604, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconlogoNotText({double size = 18.0, Color color}) => Icon(
  IconData(0xe605, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icongouwuche({double size = 18.0, Color color}) => Icon(
  IconData(0xe606, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon iconcaidan({double size = 18.0, Color color}) => Icon(
  IconData(0xe602, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian({double size = 18.0, Color color}) => Icon(
  IconData(0xe607, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian1({double size = 18.0, Color color}) => Icon(
  IconData(0xe608, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian2({double size = 18.0, Color color}) => Icon(
  IconData(0xe609, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian3({double size = 18.0, Color color}) => Icon(
  IconData(0xe60a, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian4({double size = 18.0, Color color}) => Icon(
  IconData(0xe60b, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao({double size = 18.0, Color color}) => Icon(
  IconData(0xe601, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao2({double size = 18.0, Color color}) => Icon(
  IconData(0xe60d, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian5({double size = 18.0, Color color}) => Icon(
  IconData(0xe60e, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian6({double size = 18.0, Color color}) => Icon(
  IconData(0xe60f, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian7({double size = 18.0, Color color}) => Icon(
  IconData(0xe610, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian8({double size = 18.0, Color color}) => Icon(
  IconData(0xe611, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian9({double size = 18.0, Color color}) => Icon(
  IconData(0xe612, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian10({double size = 18.0, Color color}) => Icon(
  IconData(0xe613, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian11({double size = 18.0, Color color}) => Icon(
  IconData(0xe614, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian12({double size = 18.0, Color color}) => Icon(
  IconData(0xe615, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian13({double size = 18.0, Color color}) => Icon(
  IconData(0xe616, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian14({double size = 18.0, Color color}) => Icon(
  IconData(0xe617, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian15({double size = 18.0, Color color}) => Icon(
  IconData(0xe618, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian16({double size = 18.0, Color color}) => Icon(
  IconData(0xe619, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian17({double size = 18.0, Color color}) => Icon(
  IconData(0xe61a, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian18({double size = 18.0, Color color}) => Icon(
  IconData(0xe61d, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian19({double size = 18.0, Color color}) => Icon(
  IconData(0xe61e, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian20({double size = 18.0, Color color}) => Icon(
  IconData(0xe61f, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian21({double size = 18.0, Color color}) => Icon(
  IconData(0xe620, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao3({double size = 18.0, Color color}) => Icon(
  IconData(0xe621, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao4({double size = 18.0, Color color}) => Icon(
  IconData(0xe622, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao5({double size = 18.0, Color color}) => Icon(
  IconData(0xe623, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao6({double size = 18.0, Color color}) => Icon(
  IconData(0xe624, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontupian22({double size = 18.0, Color color}) => Icon(
  IconData(0xe625, fontFamily: 'iconfont'),
  size: size,
  color: color,
);

Icon icontubiao7({double size = 18.0, Color color}) => Icon(
  IconData(0xe626, fontFamily: 'iconfont'),
  size: size,
  color: color,
);


lib/compoents/a_row/a_row.dart

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

class ARow extends StatelessWidget {
  final double height;
  final Widget leftChild;
  final Widget centerChild;
  final Widget rightChild;
  final EdgeInsets padding;
  final EdgeInsets margin;
  final Border border;
  final Color color;
  final Function onPressed;

  /// ARow 行
  /// 
  /// ```
  /// @param {double} height 高度
  /// @param {Widget} leftChild 左侧内容
  /// @param {Widget} centerChild 中间内容
  /// @param {Widget} rightChild 右侧内容
  /// @param {EdgeInsets} padding 内边距
  /// @param {EdgeInsets} margin 外边距
  /// @param {Border} border 
  /// @param {Color} color 
  /// @param {Function} onPressed 点击回调
  /// ```
  ARow({
    Key key,
    this.height = 44,
    this.padding,
    this.leftChild,
    this.centerChild,
    this.rightChild,
    this.border,
    this.color,
    this.onPressed,
    this.margin
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InkWell(
      highlightColor: onPressed == null ? Colors.transparent : null,
      splashColor: onPressed == null ? Colors.transparent : null,
      child: Container(
        height: height,
        decoration: BoxDecoration(
          // color: color == null ? hex('#fff') : color,
          border: border == null ? Border(bottom: BorderSide(width: 1, color: hex('#666'))) : border
        ),
        padding: padding == null ? EdgeInsets.symmetric(horizontal: 15) : padding,
        margin: margin == null ? EdgeInsets.all(0) : margin,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            // left
            leftChild == null ? Container() : leftChild,

            // center
            Expanded(
              child: centerChild == null ? Container() : centerChild
            ),
            
            // right
            rightChild == null ? Container() : rightChild
          ],
        ),
      ),
      onTap: () => onPressed == null ? (){} : onPressed(),
    );
  }
}

lib/pages/toolbar/mine/mine_page.dart

import 'package:color_dart/color_dart.dart';
import 'package:flutter/material.dart';
import '../../../utils/Icon.dart';
import '../../../components/a_row/a_row.dart';


class MinePage extends StatefulWidget {
  static _MinePageState _mineState;

  getAppBar() => _mineState.createAppBar();

  MinePage() {
    _mineState = _MinePageState();
  }

  _MinePageState createState() => _MinePageState();
}

class _MinePageState extends State<MinePage> {
  AppBar createAppBar() {
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Container(
        child: Column(
          children: <Widget>[
            // 头部
            Container(
              alignment: Alignment.centerLeft,
              height: 180,
              padding: EdgeInsets.only(left: 20, right: 20, top: 44),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Container(
                      alignment: Alignment.centerRight,
                      margin: EdgeInsets.only(bottom: 20),
                      child: icontupian18(
                          size: 24, color: rgba(255, 255, 255, .9))),
                  buildUser(),
                ],
              ),
            ),

            Container(
              padding: EdgeInsets.symmetric(horizontal: 15),
              child: Column(
                children: <Widget>[
                  ARow(
                    height: 50,
                    padding: EdgeInsets.all(0),
                    leftChild: Container(
                        width: 30,
                        alignment: Alignment.centerLeft,
                        child: icontupian5(
                            color: rgba(220, 220, 220, 1), size: 16)),
                    centerChild: Text('个人资料'),
                    rightChild:
                        icontupian6(color: rgba(228, 228, 228, 1), size: 14),
                  ),
                  ARow(
                    height: 50,
                    padding: EdgeInsets.all(0),
                    leftChild: Container(
                      width: 30,
                      alignment: Alignment.centerLeft,
                      child: Container(
                          padding: EdgeInsets.only(bottom: 5),
                          child: icontupian11(
                              color: rgba(220, 220, 220, 1), size: 20)),
                    ),
                    centerChild: Text('咖啡钱包'),
                    rightChild:
                        icontupian6(color: rgba(228, 228, 228, 1), size: 14),
                  ),
                  ARow(
                    height: 50,
                    padding: EdgeInsets.all(0),
                    leftChild: Container(
                      width: 30,
                      alignment: Alignment.centerLeft,
                      child: Container(
                          child: icontupian7(
                              color: rgba(220, 220, 220, 1), size: 20)),
                    ),
                    centerChild: Text('优惠券'),
                    rightChild:
                        icontupian6(color: rgba(228, 228, 228, 1), size: 14),
                    onPressed: () => {},
                  ),
                  ARow(
                    height: 50,
                    padding: EdgeInsets.all(0),
                    leftChild: Container(
                      width: 30,
                      alignment: Alignment.centerLeft,
                      child: Container(
                          child: icontupian15(
                              color: rgba(220, 220, 220, 1), size: 20)),
                    ),
                    centerChild: Text('兑换优惠'),
                    rightChild:
                        icontupian6(color: rgba(228, 228, 228, 1), size: 14),
                  ),
                  ARow(
                    height: 50,
                    padding: EdgeInsets.all(0),
                    leftChild: Container(
                      width: 30,
                      alignment: Alignment.centerLeft,
                      child: Container(
                          child: icontupian9(
                              color: rgba(220, 220, 220, 1), size: 20)),
                    ),
                    centerChild: Text('发票管理'),
                    rightChild:
                        icontupian6(color: rgba(228, 228, 228, 1), size: 14),
                    // border: G.borderBottom(show: false),
                  ),
                ],
              ),
            ),

            ARow(
              height: 50,
              margin: EdgeInsets.only(top: 10),
              padding: EdgeInsets.symmetric(horizontal: 15),
              leftChild: Container(
                width: 30,
                alignment: Alignment.centerLeft,
                child: Container(
                    child:
                        iconshoucang(color: rgba(220, 220, 220, 1), size: 20)),
              ),
              centerChild: Text('帮助反馈'),
              rightChild: icontupian6(color: rgba(228, 228, 228, 1), size: 14),
              // border: G.borderBottom(show: false),
            ),

            Container(
                margin: EdgeInsets.only(top: 10),
                padding: EdgeInsets.symmetric(horizontal: 15),
                child: Image.asset(
                  'lib/assets/images/mine/mine2.jpg',
                  fit: BoxFit.cover,
                ))
          ],
        ),
      ),
    );
  }

  ARow buildUser() {
    // UserData userData = G.user.data;

    return ARow(
      height: 55,
      color: Colors.transparent,
      // border: G.borderBottom(show: false),
      padding: EdgeInsets.all(0),
      leftChild: ClipRRect(
          borderRadius: new BorderRadius.circular(27),
          child: Image.asset(
            'lib/assets/images/mine/mine1.png',
            width: 55,
            height: 55,
            fit: BoxFit.cover,
          )),
      centerChild: Container(
        margin: EdgeInsets.only(left: 10),
        child: Text(
          '立即登录',
          style: TextStyle(color: rgba(255, 255, 255, 1), fontSize: 18),
        ),
      ),
      rightChild: icontupian6(size: 14, color: rgba(255, 255, 255, .6)),
      onPressed: () {
        // if (userData == null) return G.pushNamed('/login_mail');
      },
    );
  }
}

image.png

完善HomePage

添加flutter_swiper包

dependencies:
  flutter:
    sdk: flutter
  flutter_swiper: ^1.1.6
 

flutter_swiper文档

lib/components/custom_swiper/index.dart

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

class CustomSwiper extends StatelessWidget {
  final List<String> images;
  final int index;
  final double height;

  /// 轮播图
  /// ```
  /// @param {List<String>} images - 轮播图地址
  /// @param {int} index - 初始下标位置
  /// @param {double} height - 容器高度
  /// ```
  CustomSwiper(this.images, {
    this.index,
    this.height = 288
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      height: height,
      child: Swiper(
        index: index,
        itemBuilder: (BuildContext context,int index){
          return Image.asset(images[index], fit: BoxFit.cover);
        },
        itemCount: images.length,
        pagination: SwiperPagination(
          builder:  DotSwiperPaginationBuilder(
            size: 8,
            activeSize: 8
          )
        ),
        autoplay: true,
        duration: 500,
        autoplayDelay: 5000
      ),
    );
  }
}

lib/pages/toolbar/home_page.dart

import 'package:flutter/material.dart';
import 'package:color_dart/color_dart.dart';
import '../../../components/custom_swiper/index.dart';
import '../../../components/a_row/a_row.dart';
import '../../../utils/Icon.dart';

class HomePage extends StatelessWidget {
  HomePage({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
        child: Column(
      children: <Widget>[
        Stack(
          children: <Widget>[
            Positioned(
                child:
                    // 图轮
                    CustomSwiper(
              [
                'lib/assets/images/home/swiper1.jpg',
                'lib/assets/images/home/swiper2.jpg',
                'lib/assets/images/home/swiper3.jpg',
              ],
              height: 288,
            )),
            // 扫描二维码
            Positioned(
              top: 50,
              right: 10,
              child: rightChild(
                  icon: icontupian4(size: 20, color: hex('#fff')),
                  bgColor: rgba(0, 0, 0, .3),
                  showBorder: false),
            )
          ],
        ),
        Container(
          padding: EdgeInsets.symmetric(horizontal: 20),
          child: Column(
            children: <Widget>[
              ARow(
                height: 50,
                padding: EdgeInsets.all(2),
                leftChild: leftChild(title: '现在下单', desc: 'ORDER NOW'),
                rightChild: rightChild(
                  icon: icontupian3(color: hex('#fff'), size: 20),
                ),
              ),
              ARow(
                height: 50,
                padding: EdgeInsets.all(0),
                leftChild: leftChild(title: '现在下单', desc: 'ORDER NOW'),
                rightChild: rightChild(
                  icon: icontupian3(color: hex('#fff'), size: 20),
                ),
              ),
              ARow(
                height: 50,
                padding: EdgeInsets.all(0),
                leftChild: leftChild(title: '现在下单', desc: 'ORDER NOW'),
                rightChild: rightChild(
                  icon: icontupian3(color: hex('#fff'), size: 20),
                ),
              ),
            ],
          ),
        )
      ],
    ));
  }

  Container rightChild({Widget icon, Color bgColor, bool showBorder = true}) {
    return Container(
      width: 40,
      height: 40,
      decoration: BoxDecoration(
          color: bgColor,
          border: Border.all(
              color: showBorder ? hex('#fff') : Colors.transparent),
          borderRadius: BorderRadius.circular(20)),
      child: Container(
        padding: EdgeInsets.only(left: 2),
        child: icon,
      ),
    );
  }

  Column leftChild({String title, String desc, bool titleBlod = true}) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Row(
          children: <Widget>[
            Text(
              title,
              style: TextStyle(
                  color: hex('#fff'),
                  fontSize: 16,
                  fontWeight: titleBlod ? FontWeight.bold : FontWeight.normal),
            )
          ],
        ),
        Row(
          children: <Widget>[
            Text(
              desc,
              style: TextStyle(color: hex('#fff'), fontSize: 12),
            )
          ],
        )
      ],
    );
  }
}

image.png

数据请求

git checkout -b http

pubspec.yaml

dio: ^3.0.10
fluttertoast: ^7.1.6

Dio文档

lib/request/request.dart

import 'package:dio/dio.dart';
import './init_dio.dart';
import './req_user.dart';
class Request {
  Dio _dio;

  Request() {
     _dio = initDio();
  }

  ReqUser get user => ReqUser(_dio);
}

lib/request/init_dio.dart

import 'package:dio/dio.dart';
import '../utils/global.dart';

Dio initDio() {
  BaseOptions options = BaseOptions(
    baseUrl: "http://localhost:1323",
  );
  Dio dio = new Dio(options);
  dio.interceptors
      .add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
    return options; //continue
  }, onResponse: (Response response) async {
    print(response);
    return response; // continue
  }, onError: (DioError e) async {
    G.toast(e.message);
    return e; //continue
  }));
  return dio;
}

lib/request/req_user.dart

import 'package:dio/dio.dart';

class ReqUser {
  final Dio _dio;

  ReqUser(this._dio);
  //获取用户
  Future<Response> show() {
    return _dio.get('/users');
  }
}

lib/utils/global.dart

import '../request/reuqets.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter/material.dart';
class G {
  static final Request req = Request();
  static Future toast(String text) => Fluttertoast.showToast(
      msg: text,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
      timeInSecForIosWeb: 1,
      backgroundColor: Colors.red,
      textColor: Colors.white,
      fontSize: 16.0);
}

/lib/pages/list/list_page.dart

import 'package:flutter/material.dart';
import '../../utils/global.dart';

class ListPage extends StatefulWidget {
  ListPage({Key key}) : super(key: key);

  _ListPageState createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
 String _name = "shindou";
  @override
  void initState() {
    Future.delayed(Duration.zero, () {
      _init(context);
    });
    super.initState();
  }

  _init(BuildContext context) async {
    var res = await G.req.user.show();
    print(res);
     setState(() {
       _name = res.toString();
     });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListPage'),
      ),
      body: Center(child: Text('${_name}'))
      );
  }
}

server.go

package main

import (
  "github.com/labstack/echo/v4"
  "net/http"
)


func main(){
  e := echo.New() 
  e.GET("/users",func (c echo.Context)error{
    c.Response().Header().Set("Access-Control-Allow-Origin", "*")
 
    return c.String(http.StatusOK,'hikaru')
  })
  e.Logger.Fatal(e.Start(":1323"))
}

go run server.go

image.png image.png image.png