OpenGit_Flutter项目常用公共库总结

OpenGit_Flutter项目用到的公共库,抽取出来,便于以后的Flutter项目使用

Posted by Yuzo on July 30, 2019

OpenGit_Flutter项目常用公共库

OpenGit公共库目前包含三部分

  • 基本UI库(flutter_base_ui);
  • 常用工具类库(flutter_common_util);
  • 安装APK插件;

基本UI库

BloC和MVP基本封装

详情可以参考文章MVC、MVP、BloC、Redux四种架构在Flutter上的尝试

基本Style的提供

主要颜色,如下面代码所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class YZColors {
  static const int miWhite = 0xFFF4F5F6;

  static const int white = 0xFFFFFFFF;

  static const int mainBackgroundColor = miWhite;

  static const int textColor = 0xFF081530;
  static const int t65TextColor = 0xA6081530;
  static const int subTextColor = 0xFF8C939F;
  static const int textColorWhite = white;

  static const int redPointColor = 0xFFED5E4B;
}

文本主要样式,如下面代码所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
class YZStyle {
  static const lagerTextSize = 30.0;
  static const bigTextSize = 23.0;
  static const normalTextSize = 18.0;
  static const middleTextWhiteSize = 16.0;
  static const smallTextSize = 14.0;
  static const minTextSize = 12.0;

  static const minSubText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.subTextColor),
    fontSize: minTextSize,
  );

  static const minText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: minTextSize,
  );

  static const smallTextWhite = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: smallTextSize,
  );

  static const smallText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: smallTextSize,
  );

  static const smallTextT65 = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.t65TextColor),
    fontSize: smallTextSize,
  );

  static const smallTextBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: smallTextSize,
    fontWeight: FontWeight.bold,
  );

  static const smallSubText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.subTextColor),
    fontSize: smallTextSize,
  );

  static const middleText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: middleTextWhiteSize,
  );

  static const middleTextWhite = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: middleTextWhiteSize,
  );

  static const middleSubText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.subTextColor),
    fontSize: middleTextWhiteSize,
  );
  
  static const middleTextBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: middleTextWhiteSize,
    fontWeight: FontWeight.bold,
  );

  static const middleTextWhiteBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: middleTextWhiteSize,
    fontWeight: FontWeight.bold,
  );

  static const middleSubTextBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.subTextColor),
    fontSize: middleTextWhiteSize,
    fontWeight: FontWeight.bold,
  );

  static const normalText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: normalTextSize,
  );

  static const normalTextBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: normalTextSize,
    fontWeight: FontWeight.bold,
  );

  static const normalSubText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.subTextColor),
    fontSize: normalTextSize,
  );

  static const normalTextWhite = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: normalTextSize,
  );

  static const normalTextMitWhiteBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.miWhite),
    fontSize: normalTextSize,
    fontWeight: FontWeight.bold,
  );

  static const largeText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: bigTextSize,
  );

  static const largeTextBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: bigTextSize,
    fontWeight: FontWeight.bold,
  );

  static const largeTextWhite = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: bigTextSize,
  );

  static const largeTextWhiteBold = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: bigTextSize,
    fontWeight: FontWeight.bold,
  );

  static const largeLargeTextWhite = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColorWhite),
    fontSize: lagerTextSize,
    fontWeight: FontWeight.bold,
  );

  static const largeLargeText = TextStyle(
    fontFamily: YZFonts.montserrat_font_family,
    color: Color(YZColors.textColor),
    fontSize: lagerTextSize,
    fontWeight: FontWeight.bold,
  );
}

主要字体,如下面代码所示

1
2
3
class YZFonts {
  static const String montserrat_font_family = 'Montserrat';
}

主要图片大小,如下面代码所示

1
2
3
4
5
6
class YZSize {
  static const SMALL_IMAGE_SIZE = 18.0;
  static const NORMAL_IMAGE_SIZE = 24.0;
  static const BIG_IMAGE_SIZE = 36.0;
  static const LARGE_IMAGE_SIZE = 48.0;
}

基础Widget

图片浏览Widget

支持网络图片的加载,如下面代码所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class PhotoViewPage extends StatelessWidget {
  final String title;
  final String url;

  PhotoViewPage(this.title, this.url);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text(
          title,
          style: YZStyle.normalTextWhite,
        ),
      ),
      body: Container(
        color: Colors.black,
        child: PhotoView(
          imageProvider: NetworkImage(url),
          loadingChild: Container(
            child: Stack(
              children: <Widget>[
                Center(
                    child: ImageUtil.getImage(
                        ImagePath.image_default_head, 180.0, 180.0)),
                Center(
                  child: SpinKitCircle(color: Colors.white30, size: 25.0),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

h5网页加载Widget

支持h5链接的加载、系统浏览器打开以及分享等功能,如下面代码所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
typedef OnWillPop = void Function(BuildContext context);

class WebViewPage extends StatefulWidget {
  final String title;
  final String url;
  final OnWillPop onWillPop;

  const WebViewPage({Key key, this.title, this.url, this.onWillPop: null})
      : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return _WebViewState();
  }
}

class _WebViewState extends State<WebViewPage> {
  bool _isLoading = true;

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      child: Scaffold(
        appBar: widget.onWillPop != null
            ? null
            : AppBar(
                centerTitle: true,
                title: Text(
                  widget.title,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: YZStyle.normalTextWhite,
                ),
                actions: <Widget>[
                  PopupMenuButton(
                    padding: const EdgeInsets.all(0.0),
                    onSelected: _onPopSelected,
                    itemBuilder: (BuildContext context) =>
                        <PopupMenuItem<String>>[
                          _getPopupMenuItem('browser', Icons.language, '浏览器打开'),
                          _getPopupMenuItem('share', Icons.share, '分享'),
                    ],
                  ),
                ],
              ),
        body: Stack(
          children: <Widget>[
            _buildWebView(),
            CommonUtil.getLoading(context, _isLoading),
          ],
        ),
      ),
      onWillPop: () {
        if (widget.onWillPop != null) {
          widget.onWillPop(context);
          return Future.value(false);
        } else {
          return Future.value(true);
        }
      },
    );
  }

  Widget _buildWebView() {
    return WebView(
      onWebViewCreated: (WebViewController webViewController) {},
      initialUrl: widget.url,
      javascriptMode: JavascriptMode.unrestricted,
      onPageFinished: (url) {
        setState(() {
          _isLoading = false;
        });
      },
    );
  }

  PopupMenuItem _getPopupMenuItem(String value, IconData icon, String title) {
    return PopupMenuItem<String>(
      value: value,
      child: ListTile(
        contentPadding: EdgeInsets.all(0.0),
        dense: false,
        title: Container(
          alignment: Alignment.center,
          child: Row(
            children: <Widget>[
              Icon(
                icon,
                color: Color(YZColors.textColor),
                size: 22.0,
              ),
              SizedBox(
                width: 5.0,
              ),
              Text(
                title,
                style: YZStyle.middleText,
              )
            ],
          ),
        ),
      ),
    );
  }

  void _onPopSelected(String value) {
    switch (value) {
      case "browser":
        _launchInBrowser(widget.url, title: widget.title);
        break;
      case 'share':
        ShareUtil.share(widget.url);
        break;
    }
  }

  Future<Null> _launchInBrowser(String url, {String title}) async {
    if (await canLaunch(url)) {
      await launch(url, forceSafariVC: false, forceWebView: false);
    } else {
      throw 'Could not launch $url';
    }
  }
}

侧边栏SideBar

详情可以参考文章Flutter侧边栏控件-SideBar

常用工具类库

颜色工具类(ColorUtil)

1
2
3
4
//str->color(0x000000,0xff000000,#000000)
Color color = ColorUtil.str2Color('0xff000000');
//color->str(000000)
String color = ColorUtil.color2RGB(_currentColor);

日期工具类(DateUtil)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
///今天HH:mm
///昨天HH:mm
///星期几 HH:mm
///MM-dd HH:mm
///yyyy-MM-dd HH:mm
String date = DateUtil.getMultiDateStr(item.createdAt);

///支持的时间格式
enum DateFormat {
  yyyy_MM_dd_HH_mm_ss, //yyyy-MM-dd HH:mm:ss
  yyyy_MM_dd_HH_mm, //yyyy-MM-dd HH:mm
  yyyy_MM_dd, //yyyy-MM-dd
  yyyy_MM, //yyyy-MM
  MM_dd, //MM-dd
  MM_dd_HH_mm, //MM-dd HH:mm
  HH_mm_ss, //HH:mm:ss
  HH_mm, //HH:mm

  ZH_yyyy_MM_dd_HH_mm_ss, //yyyy年MM月dd日 HH时mm分ss秒
  ZH_yyyy_MM_dd_HH_mm, //yyyy年MM月dd日 HH时mm分
  ZH_yyyy_MM_dd, //yyyy年MM月dd日
  ZH_yyyy_MM, //yyyy年MM月
  ZH_MM_dd, //MM月dd日
  ZH_MM_dd_HH_mm, //MM月dd日 HH时mm分
  ZH_HH_mm_ss, //HH时mm分ss秒
  ZH_HH_mm, //HH时mm分
}
String date = DateUtil.getDateStrByDateTime(item.createdAt);

///周几
///zh
String weekday = DateUtil.getZHWeekDay(item.createdAt);
///en
String weekday = DateUtil.getWeekDay(item.createdAt);

文件工具类(FileUtil)

1
2
///文件大小 xB、xKB、xMB、xGB
String size = FileUtil.formatFileSize(repos.size);

图片工具类(ImageUtil)

1
2
3
/// 获取网络图片
Widget widget = ImageUtil.getCircleNetworkImage(head, 18.0, "assets/images/ic_default_head.png")
Widget widget = ImageUtil.getNetworkImage(head, 18.0, "assets/images/ic_default_head.png")

日志工具类(LogUtil)

详情信息可参考log_util

屏幕工具类(ScreenUtil)

1
2
3
///获取屏幕宽高
double width = ScreenUtil.getScreenWidth(context),
double height = ScreenUtil.getScreenHeight(context),

SP缓存工具类(SpUtil)

1
2
3
4
5
6
7
8
9
10
11
///初始化
await SpUtil.instance.init();

SpUtil.instance.putInt(SharedPrfKey.SP_KEY_CACHE_TIME, _discreteValue.round());
int time =SpUtil.instance.getInt(SharedPrfKey.SP_KEY_CACHE_TIME, defValue: 4);

SpUtil.instance.putString(SharedPrfKey.SP_KEY_TRENDING_DATE, _since);
String _since = SpUtil.instance.getString(SharedPrfKey.SP_KEY_TRENDING_DATE, defValue: 'daily');

SpUtil.instance.putObject(SharedPrfKey.SP_KEY_USER_INFO, data);
var user = SpUtil.instance.getObject(SharedPrfKey.SP_KEY_USER_INFO);

文本工具类(TextUtil)

1
2
3
4
5
TextUtil.isEmpty(colorString);

TextUtil.equals(_language, language);

List<String> repos = TextUtil.split(item.repo.name, '/');

定时器工具类(TimerUtil)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
TimerUtil.startCountdown(5, (int count) {
    next(CountdownAction(count));

    if (count == 0) {
      _jump(context, store.state.userState.status,
            store.state.userState.isGuide);
    }
});

TimerUtil.cancelCountdown();

TimerUtil.delay(500, (_) {
    viewModel.onStartCountdown();
});

Toast工具类(ToastUtil)

1
ToastUtil.showMessgae('再按一次离开App');

分享(ShareUtil)

1
ShareUtil.share(OPEN_GIT_HOME);

安装APK插件

1
InstallApkPlugin.installApk(path);

Android版安装包:

点击下载

扫码下载

Thanks For

项目地址

OpenGit客户端

flutter_common_lib

关于作者