Aqua
Utility classes/functions to help with UI development using the Flutter framework.
建议在导入包时使用 as 关键字,以避免名称冲突,例如...
import 'package:aqua/aqua.dart' as aqua
将输出日志记录到文件
await aqua.log('data to log', logFile: 'path/to/file', clear: true, time: true);
将数据保存到设备
Future<void> save() async {
var id = 'id';
var _value = 1920;
await aqua.Pref.set(id, value);
var value = await aqua.Pref.get(id);
}
将代码块放在 try catch 中
// the argument for tryCatch could either be a callback to a function or a future
// as a function
Widget _buildWidget(){
// may fail to build for some reason
}
var child = await aqua.tryCatch(_buildWidget());
// as a future
Future<Widget> _buildWidget() async {
// may fail to build for some reason
}
var future = _buildWidget();
var child = await aqua.tryCatch(future);
if(child != null){
// proceed
}
在从服务器获取 json 数据或向服务器发送 json 查询时
// posting to an endpoint
var fromServer = await aqua.Client(
'192.168.1.100', //ip
8080, // port
'/test', // endpoint
query: {
'id': 1,
}, // post parameters
// verbose: true
).getResponse();
// a real end point would look like this
// the end point is free to use
// you can find the rest of the endpoints here: https://www.coingecko.com/en/api
var fromServer = await aqua.Client(
'api.coingecko.com',
443,
'/api/v3/coins/markets',
isSecured: true,
query: {
'vs_currency': 'usd',
'order': 'market_cap_desc',
'per_page': '20',
'page': '1',
'sparkline': 'true'
}
).getResponse(method: 'GET');
仅限桌面 允许鼠标指针在悬停在可点击的小部件上时更改为点击图标
@override
Widget build(BuildContext context){
// some code
// then
return aqua.MouseInteractivity(
child: child
);
}
在一定范围的索引之间获取随机索引
var index = aqua.getRandomNumber(min: 10, max: 10000);
用不同的颜色在屏幕上输出信息
aqua.pretifyOutput('to print on screen'); // will print in green
aqua.pretifyOutput('to print on screen', color: 'red');
为图片添加阴影效果
@override
Widget build(BuildContext context){
return Stack(
children: [
_buildImage(),
aqua.Shadow(
width: width,
height: height,
)
]
);
}
一个快速的下拉小部件
@override
Widget build(BuildContext context){
return aqua.DropDown(
initValue: 'one',
items: ['one', 'two', 'three', 'four', 'five', 'six']
);
}
快速的 TabBar。没有脚手架的 Tab...
@override
Widget build(BuildContext context){
return Material(
child: DefaultTabController(
length: 3,
child: Column(
children: [
aqua.TabHeader(
tabListing: ['car', 'transit', 'bike'],
),
Expanded(
child: TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
)
],
),
)
);
}
按比例获取屏幕尺寸
@override
Widget build(BuildContext context){
aqua.Dimensions().init(context);
return Container(
width: aqua.Dimensions.width, // full width of screen
height: aqua.Dimensions.height, // full height of screen
color: Colors.red
);
}
大写一个单词
var capitalized = aqua.capitalize('alphabet');
print('capitalized: $capitalized);
快速创建一个文件(还会创建路径上的递归目录)
await aqua.createFile('/path/to/file');
// to clear a file/truncate a file
await aqua.createFile('/path/to/file', clear: true);
生成随机 ID
var id = aqua.generateUUID(length: 30);
导航
// some code
// then
aqua.Dimensions().init(context);
Widget viewOne = Container(
width: aqua.Dimensions.width,
height: aqua.Dimensions.height
color: Colors.blue
);
Widget viewTwo = Container(
width: aqua.Dimensions.width,
height: aqua.Dimensions.height
color: Colors.red
);
// to navigate to the next view without erasing the previous view from state
aqua.CustomNavigator(
context: context,
buildScreen: () = > viewOne
).navigateToPage();
// to navigate to the next view and erase the previous view from state
aqua.CustomNavigator(
context: context,
replaceSingle: true,
buildScreen: () = > viewOne
).navigateToPage();
// to navigate to the next view and erase ALL the previous views from state
aqua.CustomNavigator(
context: context,
replaceAll: true,
buildScreen: () = > viewOne
).navigateToPage();
// to navigate to the next view using a named route
aqua.CustomNavigator(
context: context,
namedRoute: '/home',
buildScreen: () = > viewOne
).navigateToPage();
显示加载图标
// render this widget as you see fit
Widget loadingIcon = aqua.LoadingIcon();
// to specify a loading type: check the different loading icons at this location
// https://github.com/jogboms/flutter_spinkit
import 'package:flutter_spinkit/flutter_spinkit.dart' as spinkitt;
Widget loadingIcon = aqua.LoadingIcon(
spinkitWidget: spinkitt.SpinKitWave(
color: Colors.blue,
size: 40.0,
),
);
请求另一小部件的焦点
@override
Widget build(BuildContext context){
// some code
// then
Widget withFocus = aqua.requestFocus(child, context: context);
// make sure to return a widget
}
为数字添加逗号
String number = aqua.pretifyNumber('1000000');
print('number: $number');
将图片裁剪成圆形小部件
@override
Widget build(BuildContext context){
// some code
// then
Widget clippedImage = aqua.ClippedCircle(
child: child // some widget, could be an image, wrapped in a container,
color: Colors.blue // border of the circle
);
// make sure to return a widget
}
自定义文本表单小部件
class Play extends StatefulWidget {
@override
PlayState createState() => PlayState();
}
class PlayState extends State<Play>{
FocusNode focusNode;
TextEditingController textEditingController;
@override
void initState(){
super.initState();
focusNode = FocusNode();
textEditingController = TextEditingController();
}
@override
void dispose(){
focusNode?.dispose();
textEditingController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context){
aqua.Dimensions().init(context);
// more on this later ...
// check source code :)
return SizedBox(
width: aqua.Dimensions.width,
height: 100.0,
child: aqua.TextFormFieldCustom(
isOutlineBorder: true, // or false
focusNode: focusNode
controller: textEditingController,
)
);
}
}
Flutter 设备 窗口导航器,需要一些样板代码才能使其工作...
要设置您的移动环境,请点击此处
要设置您的桌面环境,请点击此处
复制下面的代码以渲染如下屏幕

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:aqua/aqua.dart' as aqua;
class Shell extends StatefulWidget {
@override
ShellState createState() => ShellState();
}
class ShellState extends State<Shell>{
Widget selectedWidget;
aqua.NavigationStreamer mainNavStreamer;
StreamSubscription mainNavStreamSubscription;
@override
void initState(){
super.initState();
mainNavStreamer = aqua.NavigationStreamer();
mainNavStreamSubscription = mainNavStreamer.listen((data){
aqua.pretifyOutput('[SHELL] data from nav stream: $data');
selectedWidget = data['window'];
setState((){});
});
}
@override
void dispose(){
mainNavStreamSubscription.cancel();
mainNavStreamer.close();
super.dispose();
}
Widget _buildShell(BuildContext context){
aqua.Dimensions().init(context);
double navWidth = aqua.Dimensions.width * 0.15;
double contentWindowWidth = aqua.Dimensions.width - navWidth;
Map<String, Map<String, dynamic>> generatedRoutes = _buildGeneratedRoutes(
contentWindowWidth,
aqua.Dimensions.height
);
var textStyle = TextStyle(
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold
);
Widget firstWidget = Container(
width: contentWindowWidth,
height: aqua.Dimensions.height,
color: Colors.purple,
child: Center(
child: Text(
'Home',
style: textStyle
)
),
);
return Scaffold(
appBar: null,
body: SingleChildScrollView(
child: Container(
child: Row(
children: [
aqua.Navigation(
width: navWidth,
height: aqua.Dimensions.height,
header: Container(
width: navWidth,
height: 100.0,
color: Colors.red,
child: Center(
child: Text(
'Header',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold
),
),
),
),
routes: generatedRoutes,
bgColors: <Color>[
Colors.blue,
Colors.blueAccent
],
hoverColor: Colors.brown.withOpacity(0.5),
selectedColor: Colors.white.withOpacity(0.5),
navStreamer: mainNavStreamer,
),
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
selectedWidget == null ? aqua.requestFocus(
firstWidget,
context: context
) : aqua.requestFocus(
selectedWidget,
context: context
)
],
),
)
]
)
),
),
);
}
@override
Widget build(BuildContext context) => _buildShell(context);
Map<String, Map<String, dynamic>> _buildGeneratedRoutes(double windowWidth, double windowHeight){
var textStyle = TextStyle(
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold
);
Function _buildIconHelper = (IconData iconData){
return Icon(iconData, color: Colors.black, size: 15.0,);
};
return {
'Home': {
'window': Container(
width: windowWidth,
height: windowHeight,
color: Colors.purple,
child: Center(
child: Text(
'Home',
style: textStyle
)
),
),
'icon': _buildIconHelper(Icons.home)
},
'Search': {
'window': Container(
width: windowWidth,
height: windowHeight,
child: Stack(
children: [
aqua.Shadow(
height: windowWidth,
width: windowHeight,
colors: [
Colors.green,
Colors.teal
],
),
Center(
child: Text(
'Search',
style: textStyle
)
),
],
)
),
'icon': _buildIconHelper(Icons.search)
},
'Settings': {
'window': Container(
width: windowWidth,
height: windowHeight,
color: Colors.indigo,
child: Center(
child: Text(
'Settings',
style: textStyle
)
),
),
'icon': _buildIconHelper(Icons.settings)
}
};
}
}