This commit is contained in:
三露
2019-04-08 19:57:31 +08:00
parent cdf2cda25a
commit 5aa33abeda
435 changed files with 12113 additions and 4638 deletions

14
.gitignore vendored
View File

@ -1,6 +1,5 @@
# Miscellaneous
*.class
*.lock
*.log
*.pyc
*.swp
@ -9,9 +8,18 @@
.buildlog/
.history
.svn/
*.lock
.vscode
.gradle
.idea
/local.properties
.DS_Store
/build
.metadata
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
@ -26,7 +34,7 @@
.packages
.pub-cache/
.pub/
build/
/build/
# Android related
**/android/**/gradle-wrapper.jar

13
.vscode/launch.json vendored
View File

@ -1,13 +0,0 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart"
}
]
}

View File

@ -1,4 +0,0 @@
{
"editor.fontSize": 14,
}

86
CHANGE-LOG.md Normal file
View File

@ -0,0 +1,86 @@
## 更新日志
#### 2019-2-5
- [x] 处理因为flutter版本导致的项目运行不起来
- [x] 更新readme, 加入开发日志, 与相关说明
- [x] 加入 首页欢迎效果图
- [x] refactor(整理richText的说明):
- [x] 解决一些页面的code演示打不开的问题
- [x] add:开发规范
- [x] add:版本更新历史链接
- [x] Update README.md
- [x] add:添加版本号
- [x] feat:添加代码开发规范
- [x] refactor(update: version & fiexed warns):
- [x] fix(solve conflict):
- [x] modify:toast and andrid apk label
- [x] Add:自动 pr 工具抓取器,抓取两周前至今的,提交数据,并去重
- [x] fix:fluttetToast backHome
- [x] fix:modified the style of toast && remote files
- [x] chore(删除tools/log.json):
- [x] 重构文件结构
- [x] 关于手册图标更换
- [x] 增加demo: CupertinoNavigationBar CupertinoPageRoute CupertinoPageScaffold CupertinoPickerCupertinoPopupSurface CupertinoTimerPickerDemo
#### 2019-1-24
- [x] 功能:更新小部件的图标
- [x] 功能添加CupertinoTimerPickerDemo
- [x] 调试:消除警告
- [x] 修复:关于手册图标更换
- [x] 添加:文案描述
- [x] 添加CupertinoPickerCupertinoPopupSurface
#### 2019-1-23
- [x] 修复: 导航栏home返回报错
- [x] 修复:收集错误
- [x] 添加CupertinoNavigationBar CupertinoPageRoute CupertinoPageScaffold
#### 2019-1-22
- [x] 功能在Allsimon拉请求中添加英文简介
#### 2019-1-21
- [x] 功能Cupertino的子项
#### 2019-1-20
- [x] 功能CupertinoSwitch演示
- [x] 功能:为搜索列表加入图标
- [x] 功能CupertinoSliverRefreshControl演示
- [x] 功能CupertinoSliverNavigationBar演示
#### 2019-1-18
- [x] 更新SharedPreferences保存数据和android设备布局溢出
- [x] 功能添加CupertinoScrollbar演示
- [x] 功能:第四页暂时用欢迎页替代。后期再开发
#### 2019-1-17
- [x] 添加:+许可证
#### 2019-1-16
- [x] 转换将README翻译为En语言环境
- [x] 功能CupertinoScrollbar演示
#### 2019-1-14
- [x] 添加:增加手册页面
- [x] 功能:文字演示
- [x] 重构:修改过的图标
- [x] 重构文档文章组件收藏新增webView
- [x] 重构:修改过的演示
- [x] 重构:代码视图
- [x] 更新:版本 和readme.md
- [x] 修改:添加代码视图
- [x] 功能:添加搜索历史记录板
- [x] 修改:列出加标头错误
#### 2019-1-15
- [x] 功能welcomepage
#### 2019-1-13
- [x] 添加:一些输入描述
- [x] 功能加入GridPaperSliverGrid
- [x] 重构修改db
- [x] 重构:删除数据库 TabBarView
- [x] 添加:网格视图
- [x] 修改checkbosListTile 错误
- [x] 修改:自动提示文案
- [x] 功能:增加免责声明,声明组件,自动弹出,左上角入口
- [x] 重构整理数据库初始逻辑判断数据库完整性判断是否存在已知的catwidgetcollection 三张表。
- [x] 修复DialogDemo无法关闭的问题
#### 2019-1-12
- [x] 修复icon没有但内容有的组件给补充了icon
- [x] 修改1.整理文件 2.修正分析
- [x] 更新flutter_rookie_book => flutter_go
- [x] 更新更新SearchInput文件名=> search_input
- [x] 修改:文件名称的大小写规范
- [x] 修改修正bottomNavigationBar iconButton警告

View File

@ -0,0 +1,679 @@
# Flutter Go 代码开发规范 0.1.0 版
## 代码风格
### 标识符三种类型
#### 大驼峰
类、枚举、typedef和类型参数
```
class SliderMenu { ... }
class HttpRequest { ... }
typedef Predicate = bool Function<T>(T value);
```
包括用于元数据注释的类
```
class Foo {
const Foo([arg]);
}
@Foo(anArg)
class A { ... }
@Foo()
class B { ... }
```
#### 使用小写加下划线来命名库和源文件
```
library peg_parser.source_scanner;
import 'file_system.dart';
import 'slider_menu.dart';
```
不推荐如下写法:
```
library pegparser.SourceScanner;
import 'file-system.dart';
import 'SliderMenu.dart';
```
#### 使用小写加下划线来命名导入前缀
```
import 'dart:math' as math;
import 'package:angular_components/angular_components'
as angular_components;
import 'package:js/js.dart' as js;
```
不推荐如下写法:
```
import 'dart:math' as Math;
import 'package:angular_components/angular_components'
as angularComponents;
import 'package:js/js.dart' as JS;
```
#### 使用小驼峰法命名其他标识符
```
var item;
HttpRequest httpRequest;
void align(bool clearItems) {
// ...
}
```
#### 优先使用小驼峰法作为常量命名
```
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}
```
不推荐如下写法:
```
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');
class Dice {
static final NUMBER_GENERATOR = Random();
}
```
#### 不使用前缀字母
因为Dart可以告诉您声明的类型、范围、可变性和其他属性所以没有理由将这些属性编码为标识符名称。
```
defaultTimeout
```
不推荐如下写法:
```
kDefaultTimeout
```
### 排序
为了使你的文件前言保持整洁,我们有规定的命令,指示应该出现在其中。每个“部分”应该用空行分隔。
#### 在其他引入之前引入所需的dart库
```
import 'dart:async';
import 'dart:html';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
```
#### 在相对引入之前先引入在包中的库
```
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'util.dart';
```
#### 第三方包的导入先于其他包
```
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'package:my_package/util.dart';
```
#### 在所有导入之后,在单独的部分中指定导出
```
import 'src/error.dart';
import 'src/foo_bar.dart';
export 'src/error.dart';
```
不推荐如下写法:
```
import 'src/error.dart';
export 'src/error.dart';
import 'src/foo_bar.dart';
```
### 所有流控制结构,请使用大括号
这样做可以避免悬浮的else问题
```
if (isWeekDay) {
print('Bike to work!');
} else {
print('Go dancing or read a book!');
}
```
#### 例外
一个if语句没有else子句其中整个if语句和then主体都适合一行。在这种情况下如果你喜欢的话你可以去掉大括号
```
if (arg == null) return defaultValue;
```
如果流程体超出了一行需要分划请使用大括号:
```
if (overflowChars != other.overflowChars) {
return overflowChars < other.overflowChars;
}
```
不推荐如下写法:
```
if (overflowChars != other.overflowChars)
return overflowChars < other.overflowChars;
```
## 注释
### 要像句子一样格式化
除非是区分大小写的标识符,否则第一个单词要大写。以句号结尾(或“!”或“?”)。对于所有的注释都是如此doc注释、内联内容甚至TODOs。即使是一个句子片段。
```
greet(name) {
// Assume we have a valid name.
print('Hi, $name!');
}
```
不推荐如下写法:
```
greet(name) {
/* Assume we have a valid name. */
print('Hi, $name!');
}
```
可以使用块注释(/…/)临时注释掉一段代码,但是所有其他注释都应该使用//
### Doc注释
使用///文档注释来记录成员和类型。
使用doc注释而不是常规注释可以让dartdoc找到并生成文档。
```
/// The number of characters in this chunk when unsplit.
int get length => ...
```
> 由于历史原因,达特茅斯学院支持道格评论的两种语法:///(“C#风格”)和/**…* /(“JavaDoc风格”)。我们更喜欢/// 因为它更紧凑。/**和*/在多行文档注释中添加两个无内容的行。在某些情况下,///语法也更容易阅读,例如文档注释包含使用*标记列表项的项目符号列表。
### 考虑为私有api编写文档注释
Doc注释并不仅仅针对库的公共API的外部使用者。它们还有助于理解从库的其他部分调用的私有成员
#### 用一句话总结开始doc注释
以简短的、以用户为中心的描述开始你的文档注释,以句号结尾。
```
/// Deletes the file at [path] from the file system.
void delete(String path) {
...
}
```
不推荐如下写法:
```
/// Depending on the state of the file system and the user's permissions,
/// certain operations may or may not be possible. If there is no file at
/// [path] or it can't be accessed, this function throws either [IOError]
/// or [PermissionError], respectively. Otherwise, this deletes the file.
void delete(String path) {
...
}
```
#### “doc注释”的第一句话分隔成自己的段落
在第一个句子之后添加一个空行,把它分成自己的段落
```
/// Deletes the file at [path].
///
/// Throws an [IOError] if the file could not be found. Throws a
/// [PermissionError] if the file is present but could not be deleted.
void delete(String path) {
...
}
```
## Flutter_Go 使用参考
### 库的引用
flutter go 中导入lib下文件库统一指定包名避免过多的```../../```
```
package:flutter_go/
```
### 字符串的使用
#### 使用相邻字符串连接字符串文字
如果有两个字符串字面值(不是值,而是实际引用的字面值),则不需要使用+连接它们。就像在C和c++中,简单地把它们放在一起就能做到。这是创建一个长字符串很好的方法但是不适用于单独一行。
```
raiseAlarm(
'ERROR: Parts of the spaceship are on fire. Other '
'parts are overrun by martians. Unclear which are which.');
```
不推荐如下写法:
```
raiseAlarm('ERROR: Parts of the spaceship are on fire. Other ' +
'parts are overrun by martians. Unclear which are which.');
```
#### 优先使用模板字符串
```
'Hello, $name! You are ${year - birth} years old.';
```
#### 在不需要的时候,避免使用花括号
```
'Hi, $name!'
"Wear your wildest $decade's outfit."
```
不推荐如下写法:
```
'Hello, ' + name + '! You are ' + (year - birth).toString() + ' y...';
```
不推荐如下写法:
```
'Hi, ${name}!'
"Wear your wildest ${decade}'s outfit."
```
### 集合
#### 尽可能使用集合字面量
如果要创建一个不可增长的列表,或者其他一些自定义集合类型,那么无论如何,都要使用构造函数。
```
var points = [];
var addresses = {};
var lines = <Lines>[];
```
不推荐如下写法:
```
var points = List();
var addresses = Map();
```
#### 不要使用.length查看集合是否为空
```
if (lunchBox.isEmpty) return 'so hungry...';
if (words.isNotEmpty) return words.join(' ');
```
不推荐如下写法:
```
if (lunchBox.length == 0) return 'so hungry...';
if (!words.isEmpty) return words.join(' ');
```
#### 考虑使用高阶方法转换序列
如果有一个集合,并且希望从中生成一个新的修改后的集合,那么使用.map()、.where()和Iterable上的其他方便的方法通常更短也更具有声明性
```
var aquaticNames = animals
.where((animal) => animal.isAquatic)
.map((animal) => animal.name);
```
#### 避免使用带有函数字面量的Iterable.forEach()
在Dart中如果你想遍历一个序列惯用的方法是使用循环。
```
for (var person in people) {
...
}
```
不推荐如下写法:
```
people.forEach((person) {
...
});
```
#### 不要使用List.from(),除非打算更改结果的类型
给定一个迭代,有两种明显的方法可以生成包含相同元素的新列表
```
var copy1 = iterable.toList();
var copy2 = List.from(iterable);
```
明显的区别是第一个比较短。重要的区别是第一个保留了原始对象的类型参数
```
// Creates a List<int>:
var iterable = [1, 2, 3];
// Prints "List<int>":
print(iterable.toList().runtimeType);
```
```
// Creates a List<int>:
var iterable = [1, 2, 3];
// Prints "List<dynamic>":
print(List.from(iterable).runtimeType);
```
### 参数的使用
#### 使用=将命名参数与其默认值分割开
由于遗留原因Dart均允许“:”和“=”作为指定参数的默认值分隔符。为了与可选的位置参数保持一致,使用“=”。
```
void insert(Object item, {int at = 0}) { ... }
```
不推荐如下写法:
```
void insert(Object item, {int at: 0}) { ... }
```
#### 不要使用显式默认值null
如果参数是可选的但没有给它一个默认值则语言隐式地使用null作为默认值因此不需要编写它
```
void error([String message]) {
stderr.write(message ?? '\n');
}
```
不推荐如下写法:
```
void error([String message = null]) {
stderr.write(message ?? '\n');
}
```
### 变量
#### 不要显式地将变量初始化为空
在Dart中未显式初始化的变量或字段自动被初始化为null。不要多余赋值null
```
int _nextId;
class LazyId {
int _id;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
```
不推荐如下写法:
```
int _nextId = null;
class LazyId {
int _id = null;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
```
#### 避免储存你能计算的东西
在设计类时,您通常希望将多个视图公开到相同的底层状态。通常你会看到在构造函数中计算所有视图的代码,然后存储它们:
应该避免的写法:
```
class Circle {
num radius;
num area;
num circumference;
Circle(num radius)
: radius = radius,
area = pi * radius * radius,
circumference = pi * 2.0 * radius;
}
```
如上代码问题:
- 浪费内存
- 缓存的问题是无效——如何知道何时缓存过期需要重新计算?
推荐的写法如下:
```
class Circle {
num radius;
Circle(this.radius);
num get area => pi * radius * radius;
num get circumference => pi * 2.0 * radius;
}
```
### 类成员
#### 不要把不必要地将字段包装在getter和setter中
不推荐如下写法:
```
class Box {
var _contents;
get contents => _contents;
set contents(value) {
_contents = value;
}
}
```
#### 优先使用final字段来创建只读属性
尤其对于 ```StatelessWidget```
#### 在不需要的时候不要用this
不推荐如下写法:
```
class Box {
var value;
void clear() {
this.update(null);
}
void update(value) {
this.value = value;
}
}
```
推荐如下写法:
```
class Box {
var value;
void clear() {
update(null);
}
void update(value) {
this.value = value;
}
}
```
### 构造函数
#### 尽可能使用初始化的形式
不推荐如下写法:
```
class Point {
num x, y;
Point(num x, num y) {
this.x = x;
this.y = y;
}
}
```
推荐如下写法:
```
class Point {
num x, y;
Point(this.x, this.y);
}
```
#### 不要使用new
Dart2使new 关键字可选
推荐写法:
```
Widget build(BuildContext context) {
return Row(
children: [
RaisedButton(
child: Text('Increment'),
),
Text('Click!'),
],
);
}
```
不推荐如下写法:
```
Widget build(BuildContext context) {
return new Row(
children: [
new RaisedButton(
child: new Text('Increment'),
),
new Text('Click!'),
],
);
}
```
### 异步
#### 优先使用async/await代替原始的futures
async/await语法提高了可读性允许你在异步代码中使用所有Dart控制流结构。
```
Future<int> countActivePlayers(String teamName) async {
try {
var team = await downloadTeam(teamName);
if (team == null) return 0;
var players = await team.roster;
return players.where((player) => player.isActive).length;
} catch (e) {
log.error(e);
return 0;
}
}
```
#### 当异步没有任何用处时,不要使用它
如果可以在不改变函数行为的情况下省略异步,那么就这样做。、
```
Future afterTwoThings(Future first, Future second) {
return Future.wait([first, second]);
}
```
不推荐写法:
```
Future afterTwoThings(Future first, Future second) async {
return Future.wait([first, second]);
}
```

88
README-en.md Normal file
View File

@ -0,0 +1,88 @@
## Flutter Go
![https://img.alicdn.com/tfs/TB1OJkeHNYaK1RjSZFnXXa80pXa-229-229.png](https://img.alicdn.com/tfs/TB1OJkeHNYaK1RjSZFnXXa80pXa-229-229.png)
> Help developers get started quickly Flutter **Flutter Go 1.0 Android has been released**
## Download URL
Android download URL:
<img src="https://img.alicdn.com/tfs/TB180.kOhYaK1RjSZFnXXa80pXa-442-420.png" width="200px">
Iphone download URL:
No
## Development Environment
This Project need latest package, please update regularly.
- dart(version: 2.0.0)
- flutter(version: v1.0.0)
### Background
#### What is Flutter?
On June 21, 2018, Google released the first release preview of Flutter as a new responsive, cross-platform, high-performance mobile development framework launched by Google. Flutter is a cross-platform mobile UI framework designed to help developers develop high-performance, high-fidelity Android and iOS apps using a single set of code.
The advantages of Flutter mainly include:
- Cross-platform
- Open source
- Hot Reload, responsive framework, and its rich controls and development tools
- Flexible interface design and control combinations
- High quality user experience with a portable GPU-accelerated rendering engine and high-performance ARM code runtime
#### The origin of Flutter Go
- Flutter has too little learning material, which is relatively difficult for students who are not good at English.
- The official website document example is not sound enough, not intuitive enough
- The usage of each widget is different, and the properties are numerous. To run a demo of a widget, it is often necessary to look through various materials everywhere.
#### Advantages of Flutter Go
- Detailed idiom widgets up to **130+**
- Companion Demo Explain the widget's general usage
- Centralized integration of widget cases, an APP to get all the usage of common widgets
- Continuous iteration chasing new official version
### App Preview
<img src="https://img.alicdn.com/tfs/TB1oeicBhjaK1RjSZFAXXbdLFXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB1WJNuBmzqK1RjSZPcXXbTepXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB13Xh3BkvoK1RjSZFNXXcxMVXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB1MtdSBjDpK1RjSZFrXXa78VXa-345-717.gif" width=200>
### Core Team
<table>
<tbody>
<tr>
<td align="center" width="80" valign="top">
<img height="80" width="80" src="https://github.com/minghe.png?s=128">
<br>
<a href="https://github.com/minghe">@minghe</a>
</td>
<td align="center" width="80" valign="top">
<img height="80" width="80" src="https://github.com/ryan730.png?s=128">
<br>
<a href="https://github.com/ryan730">@ryan730</a>
</td>
<td align="center" width="80" valign="top">
<img height="80" width="80" src="https://github.com/Nealyang.png?s=128">
<br>
<a href="https://github.com/Nealyang">@Nealyang</a>
</td>
<td align="center" width="80" valign="top">
<img height="80" width="80" src="https://github.com/hanxu317317.png?s=128">
<br>
<a href="https://github.com/hanxu317317">@hanxu317317</a>
</td>
<td align="center" width="80" valign="top">
<img height="80" width="80" src="https://github.com/DeckeDeng.png?s=128">
<br>
<a href="https://github.com/DeckeDeng">@DeckeDeng</a>
</td>
</tr>
</tbody>
</table>
Powered by [Alibaba Auction Front-end Team](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width= 20 height=20>

View File

@ -1,17 +1,36 @@
Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.md) | [中文简体](https://github.com/alibaba/flutter-go/blob/master/README.md)
## Flutter Go
> 帮助开发者快速上手 Flutter **内部测试中1.0 正式版将于 2月 20日 发布。**
![https://img.alicdn.com/tfs/TB1OJkeHNYaK1RjSZFnXXa80pXa-229-229.png](https://img.alicdn.com/tfs/TB1OJkeHNYaK1RjSZFnXXa80pXa-229-229.png)
> 帮助开发者快速上手 Flutter **Flutter Go 1.0 Android版已正式发布**
## 版本更新历史
> 按时间顺序,展示重要的提交更新内容。
[地址](https://github.com/alibaba/flutter-go/blob/develop/CHANGE-LOG.md)
## 开发规范
> 由于类似 javascript, java, object-c,等开发者的语言习惯不同而产生歧义,我们依据官方提供的 [dart 语言规范](https://www.dartlang.org) 定制。
[<< Flutter Go 开发规范第一版 >>](https://github.com/alibaba/flutter-go/blob/develop/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md)
## Release安装包下载地址
android下载地址:
<img src="https://img.alicdn.com/tfs/TB1q1GVB4naK1RjSZFtXXbC2VXa-195-198.png" width="200px">
<img src="https://img.alicdn.com/tfs/TB180.kOhYaK1RjSZFnXXa80pXa-442-420.png" width="200px">
iphone下载地址:
暂无
## 基础环境
本项目环境持续更新. 请定期更新各依赖包.
- dart(version: 2.0.0)
- flutter(version: v1.0.0)
### 背景
#### Flutter 是什么?
@ -33,14 +52,15 @@ flutter优点主要包括
#### Flutter Go 的优势
- 详解常用widget多达 **130+**
- 详解常用widget多达 **140+**
- 配套 Demo 详解 widget 常规用法
- 集中整合 widget 案例,一个 APP 搞定所有常用 widget 的用法
- 持续迭代 ‘追新’ 官方版本
### app 预览
<img src="https://img.alicdn.com/tfs/TB1oeicBhjaK1RjSZFAXXbdLFXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB1WJNuBmzqK1RjSZPcXXbTepXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB13Xh3BkvoK1RjSZFNXXcxMVXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB1MtdSBjDpK1RjSZFrXXa78VXa-345-717.gif" width=200>
<img src="https://img.alicdn.com/tfs/TB1MoiNExTpK1RjSZFGXXcHqFXa-362-751.gif" width=200> <img src="https://img.alicdn.com/tfs/TB1oeicBhjaK1RjSZFAXXbdLFXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB1WJNuBmzqK1RjSZPcXXbTepXa-345-717.gif" width=200> <img src="https://img.alicdn.com/tfs/TB13Xh3BkvoK1RjSZFNXXcxMVXa-345-717.gif" width=200>
### Core Team

View File

@ -22,18 +22,23 @@ if (flutterVersionName == null) {
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 27
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.flutterrookiebook"
applicationId "com.ali.fluttergo"
minSdkVersion 16
targetSdkVersion 27
versionCode flutterVersionCode.toInteger()
@ -55,6 +60,7 @@ flutter {
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ali.fluttergo">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -1,28 +1,25 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flutterrookiebook">
<!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODE_WORLD_READABLE"/>
<uses-permission android:name="android.permission.MODE_WORLD_WRITEABLE"/>
package="com.ali.fluttergo">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODE_WORLD_READABLE"/>
<uses-permission android:name="android.permission.MODE_WORLD_WRITEABLE"/>
<application
android:name="io.flutter.app.FlutterApplication"
android:label="菜鸟手册"
android:icon="@drawable/logo">
android:label="fluttergo"
android:icon="@mipmap/ic_launcher_logo">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing

View File

@ -0,0 +1,13 @@
package com.ali.fluttergo
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -4,9 +4,9 @@
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
android:src="@mipmap/splash" />
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/splash">
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ali.fluttergo">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -1,4 +1,5 @@
buildscript {
ext.kotlin_version = '1.2.71'
repositories {
google()
jcenter()
@ -6,6 +7,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/fonts/Lato-Bold.ttf Executable file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

View File

@ -7,8 +7,24 @@
objects = {
/* Begin PBXBuildFile section */
0828E495220692B500A59437 /* iPhone Portrait-Retina 4.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E486220692B400A59437 /* iPhone Portrait-Retina 4.png */; };
0828E496220692B500A59437 /* iPad Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E487220692B400A59437 /* iPad Portrait.png */; };
0828E497220692B500A59437 /* iPhone X_XS Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E488220692B400A59437 /* iPhone X_XS Landscape.png */; };
0828E498220692B500A59437 /* iPhone XS Max Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E489220692B400A59437 /* iPhone XS Max Portrait.png */; };
0828E499220692B500A59437 /* iPhone Portrait-Retina HD 4.7.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E48A220692B400A59437 /* iPhone Portrait-Retina HD 4.7.png */; };
0828E49A220692B500A59437 /* iPhone X_XS Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E48B220692B400A59437 /* iPhone X_XS Portrait.png */; };
0828E49B220692B500A59437 /* iPad Landscape@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E48C220692B400A59437 /* iPad Landscape@2x.png */; };
0828E49C220692B500A59437 /* iPhone Landscape-Retina HD 5.5.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E48D220692B400A59437 /* iPhone Landscape-Retina HD 5.5.png */; };
0828E49D220692B500A59437 /* iPhone Portrait@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E48E220692B400A59437 /* iPhone Portrait@2x.png */; };
0828E49E220692B500A59437 /* iPad Portrait@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E48F220692B400A59437 /* iPad Portrait@2x.png */; };
0828E49F220692B500A59437 /* iPhone XS Max Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E490220692B400A59437 /* iPhone XS Max Landscape.png */; };
0828E4A0220692B500A59437 /* iPad Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E491220692B500A59437 /* iPad Landscape.png */; };
0828E4A1220692B500A59437 /* iPhone XR Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E492220692B500A59437 /* iPhone XR Portrait.png */; };
0828E4A2220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E493220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png */; };
0828E4A3220692B500A59437 /* iPhone XR Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 0828E494220692B500A59437 /* iPhone XR Landscape.png */; };
0828E4A52206936100A59437 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0828E4A42206936100A59437 /* Images.xcassets */; };
084A20882202E4FD00428FF5 /* flutter go.png in Resources */ = {isa = PBXBuildFile; fileRef = 084A20872202E4FD00428FF5 /* flutter go.png */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
333E5DAE7FC10AC69FEC26C0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA792F029EDD7A11295D192 /* libPods-Runner.a */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
@ -38,9 +54,25 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
0828E486220692B400A59437 /* iPhone Portrait-Retina 4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone Portrait-Retina 4.png"; sourceTree = "<group>"; };
0828E487220692B400A59437 /* iPad Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPad Portrait.png"; sourceTree = "<group>"; };
0828E488220692B400A59437 /* iPhone X_XS Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone X_XS Landscape.png"; sourceTree = "<group>"; };
0828E489220692B400A59437 /* iPhone XS Max Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone XS Max Portrait.png"; sourceTree = "<group>"; };
0828E48A220692B400A59437 /* iPhone Portrait-Retina HD 4.7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone Portrait-Retina HD 4.7.png"; sourceTree = "<group>"; };
0828E48B220692B400A59437 /* iPhone X_XS Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone X_XS Portrait.png"; sourceTree = "<group>"; };
0828E48C220692B400A59437 /* iPad Landscape@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPad Landscape@2x.png"; sourceTree = "<group>"; };
0828E48D220692B400A59437 /* iPhone Landscape-Retina HD 5.5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone Landscape-Retina HD 5.5.png"; sourceTree = "<group>"; };
0828E48E220692B400A59437 /* iPhone Portrait@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone Portrait@2x.png"; sourceTree = "<group>"; };
0828E48F220692B400A59437 /* iPad Portrait@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPad Portrait@2x.png"; sourceTree = "<group>"; };
0828E490220692B400A59437 /* iPhone XS Max Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone XS Max Landscape.png"; sourceTree = "<group>"; };
0828E491220692B500A59437 /* iPad Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPad Landscape.png"; sourceTree = "<group>"; };
0828E492220692B500A59437 /* iPhone XR Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone XR Portrait.png"; sourceTree = "<group>"; };
0828E493220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone Portrait-Retina HD 5.5.png"; sourceTree = "<group>"; };
0828E494220692B500A59437 /* iPhone XR Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iPhone XR Landscape.png"; sourceTree = "<group>"; };
0828E4A42206936100A59437 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
084A20872202E4FD00428FF5 /* flutter go.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flutter go.png"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -72,6 +104,28 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0828E485220692A700A59437 /* launch */ = {
isa = PBXGroup;
children = (
0828E491220692B500A59437 /* iPad Landscape.png */,
0828E48C220692B400A59437 /* iPad Landscape@2x.png */,
0828E48F220692B400A59437 /* iPad Portrait@2x.png */,
0828E487220692B400A59437 /* iPad Portrait.png */,
0828E48D220692B400A59437 /* iPhone Landscape-Retina HD 5.5.png */,
0828E486220692B400A59437 /* iPhone Portrait-Retina 4.png */,
0828E48A220692B400A59437 /* iPhone Portrait-Retina HD 4.7.png */,
0828E493220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png */,
0828E48E220692B400A59437 /* iPhone Portrait@2x.png */,
0828E488220692B400A59437 /* iPhone X_XS Landscape.png */,
0828E48B220692B400A59437 /* iPhone X_XS Portrait.png */,
0828E494220692B500A59437 /* iPhone XR Landscape.png */,
0828E492220692B500A59437 /* iPhone XR Portrait.png */,
0828E490220692B400A59437 /* iPhone XS Max Landscape.png */,
0828E489220692B400A59437 /* iPhone XS Max Portrait.png */,
);
path = launch;
sourceTree = "<group>";
};
0C172CA58CDB230D5DA80034 /* Pods */ = {
isa = PBXGroup;
children = (
@ -90,7 +144,6 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
@ -104,6 +157,8 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
0828E485220692A700A59437 /* launch */,
084A20872202E4FD00428FF5 /* flutter go.png */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
@ -132,6 +187,7 @@
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
0828E4A42206936100A59437 /* Images.xcassets */,
);
path = Runner;
sourceTree = "<group>";
@ -207,11 +263,27 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0828E4A0220692B500A59437 /* iPad Landscape.png in Resources */,
0828E4A1220692B500A59437 /* iPhone XR Portrait.png in Resources */,
0828E49F220692B500A59437 /* iPhone XS Max Landscape.png in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
0828E4A3220692B500A59437 /* iPhone XR Landscape.png in Resources */,
0828E4A2220692B500A59437 /* iPhone Portrait-Retina HD 5.5.png in Resources */,
0828E49A220692B500A59437 /* iPhone X_XS Portrait.png in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
0828E49E220692B500A59437 /* iPad Portrait@2x.png in Resources */,
0828E49D220692B500A59437 /* iPhone Portrait@2x.png in Resources */,
0828E499220692B500A59437 /* iPhone Portrait-Retina HD 4.7.png in Resources */,
084A20882202E4FD00428FF5 /* flutter go.png in Resources */,
0828E497220692B500A59437 /* iPhone X_XS Landscape.png in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
0828E4A52206936100A59437 /* Images.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
0828E49B220692B500A59437 /* iPad Landscape@2x.png in Resources */,
0828E495220692B500A59437 /* iPhone Portrait-Retina 4.png in Resources */,
0828E498220692B500A59437 /* iPhone XS Max Portrait.png in Resources */,
0828E496220692B500A59437 /* iPad Portrait.png in Resources */,
0828E49C220692B500A59437 /* iPhone Landscape-Retina HD 5.5.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -237,11 +309,15 @@
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
@ -269,11 +345,15 @@
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios-release/Flutter.framework",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
);
@ -428,6 +508,7 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = RDJKXT446D;
ENABLE_BITCODE = NO;
@ -441,7 +522,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterRookieBook;
PRODUCT_BUNDLE_IDENTIFIER = com.ali.flutterRookieBook;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
@ -452,6 +533,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = RDJKXT446D;
ENABLE_BITCODE = NO;
@ -465,7 +547,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterRookieBook;
PRODUCT_BUNDLE_IDENTIFIER = com.ali.flutterRookieBook;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};

View File

@ -7,6 +7,7 @@
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
[NSThread sleepForTimeInterval:2];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

View File

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,20 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,201 @@
{
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2688h",
"filename" : "iPhone XS Max Portrait.png",
"minimum-system-version" : "12.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"orientation" : "landscape",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "12.0",
"subtype" : "2688h",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "1792h",
"filename" : "iPhone XR Portrait.png",
"minimum-system-version" : "12.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "12.0",
"subtype" : "1792h",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2436h",
"filename" : "iPhone X_XS Portrait.png",
"minimum-system-version" : "11.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"orientation" : "landscape",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "11.0",
"subtype" : "2436h",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "iPhone Portrait-Retina HD 5.5.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"orientation" : "landscape",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "8.0",
"subtype" : "736h",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "iPhone Portrait-Retina HD 4.7.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "iPhone Portrait@2x.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "iPhone Portrait-Retina 4.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "iPad Portrait.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"filename" : "iPad Landscape.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "iPad Portrait@2x.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"filename" : "iPad Landscape@2x.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"subtype" : "retina4",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

View File

@ -2,17 +2,29 @@
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"filename" : "flutter go.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"filename" : "flutter go-1.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"filename" : "flutter go-2.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x"
}
],
@ -20,4 +32,4 @@
"version" : 1,
"author" : "xcode"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

View File

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
@ -14,24 +18,30 @@
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
<constraint firstAttribute="bottom" secondItem="YRO-k0-Ey4" secondAttribute="bottom" id="T5g-9A-c9v"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="eyW-WF-YgD"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="veX-UW-bF2"/>
<constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="yhF-ag-fuv"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
<point key="canvasLocation" x="84.799999999999997" y="337.33133433283359"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
<image name="LaunchImage" width="1080" height="1920"/>
</resources>
</document>

View File

@ -0,0 +1,49 @@
{
"images" : [
{
"orientation" : "portrait",
"idiom" : "ipad",
"minimum-system-version" : "7.0",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"minimum-system-version" : "7.0",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"minimum-system-version" : "7.0",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"minimum-system-version" : "7.0",
"subtype" : "retina4",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"minimum-system-version" : "7.0",
"extent" : "full-screen",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>菜鸟App</string>
<string>Flutter Go</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

BIN
ios/flutter go.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import '../model/cat.dart';
import '../common/widget_name_to_icon.dart';
import '../resources/widget_name_to_icon.dart';
import '../components/widget_item_container.dart';
class CateCard extends StatefulWidget {

View File

@ -0,0 +1,143 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../routers/application.dart';
import '../model/cat.dart';
import '../model/widget.dart';
import '../widgets/index.dart';
import '../components/widget_item_container.dart';
enum CateOrWigdet { Cat, WidgetDemo }
class CategoryHome extends StatefulWidget {
CategoryHome(this.name);
final String name;
@override
_CategoryHome createState() => new _CategoryHome();
}
class _CategoryHome extends State<CategoryHome> {
String title = '';
// 显示列表 cat or widget;
List<Cat> categories = [];
List<WidgetPoint> widgetPoints = [];
List<Cat> catHistory = new List();
CatControlModel catControl = new CatControlModel();
WidgetControlModel widgetControl = new WidgetControlModel();
// 所有的可用demos;
List widgetDemosList = new WidgetDemoList().getDemos();
@override
void initState() {
super.initState();
// 初始化加入顶级的name
this.getCatByName(widget.name).then((Cat cat) {
catHistory.add(cat);
searchCatOrWigdet();
});
}
Future<Cat> getCatByName(String name) async {
return await catControl.getCatByName(name);
}
Future<bool> back() {
if (catHistory.length == 1) {
return Future<bool>.value(true);
}
catHistory.removeLast();
searchCatOrWigdet();
return Future<bool>.value(false);
}
void go(Cat cat) {
catHistory.add(cat);
searchCatOrWigdet();
}
void searchCatOrWigdet() async {
// 假设进入这个界面的parent一定存在
Cat parentCat = catHistory.last;
// 继续搜索显示下一级depth: depth + 1, parentId: parentCat.id
List<Cat> _categories =
await catControl.getList(new Cat(parentId: parentCat.id));
List<WidgetPoint> _widgetPoints = new List();
if (_categories.isEmpty) {
_widgetPoints =
await widgetControl.getList(new WidgetPoint(catId: parentCat.id));
}
this.setState(() {
categories = _categories;
title = parentCat.name;
widgetPoints = _widgetPoints;
});
}
void onCatgoryTap(Cat cat) {
go(cat);
}
void onWidgetTap(WidgetPoint widgetPoint) {
String targetName = widgetPoint.name;
String targetRouter = '/category/error/404';
widgetDemosList.forEach((item) {
// print("targetRouter = item.routerName> ${[item.name,targetName]}");
if (item.name == targetName) {
targetRouter = item.routerName;
}
});
Application.router.navigateTo(context, "$targetRouter");
}
Widget _buildContent() {
WidgetItemContainer wiContaienr = WidgetItemContainer(
columnCount: 3,
categories: categories,
isWidgetPoint:false
);
if (widgetPoints.length > 0) {
wiContaienr = WidgetItemContainer(
categories: widgetPoints,
columnCount: 3,
isWidgetPoint:true
);
}
return Container(
padding: const EdgeInsets.only(bottom: 10.0, top: 5.0),
decoration: BoxDecoration(
color: Colors.white,
image: DecorationImage(
image: AssetImage('assets/images/paimaiLogo.png'),
alignment: Alignment.bottomRight),
),
child: wiContaienr,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: WillPopScope(
onWillPop: () {
return back();
},
child: ListView(
children: <Widget>[
_buildContent(),
],
),
// child: Container(color: Colors.blue,child: Text('123'),),
),
);
}
}

View File

@ -1,265 +1,196 @@
/**
* Created with Android Studio.
* User: 一晟
* Date: 2019/1/12
* Time: 下午9:19
* email: zhu.yan@alibaba-inc.com
*/
/// Created with Android Studio.
/// User: 一晟
/// Date: 2019/1/12
/// Time: 下午9:19
/// email: zhu.yan@alibaba-inc.com
import 'dart:async';
import 'package:flutter/material.dart';
//import 'package:flutter_rookie_book/model/collection_general.dart';
//import 'package:flutter_rookie_book/model/collection_general.dart';
import 'package:shared_preferences/shared_preferences.dart';
const disclaimerText1 = '\r\r\r\r\r\r本APP属于个人的非赢利性开源项目以供开源社区使用凡本APP转载的所有的文章 、图片、音频、视频文件等资料的版权归版权所有人所有本APP采用的非本站原创文章及图片等内容无法一一和版权者联系如果本网所选内容的文章作者及编辑认为其作品不宜上网供大家浏览或不应无偿使用请及时用电子邮件或电话通知我们以迅速采取适当措施避免给双方造成不必要的经济损失。';
const disclaimerText2 = '\n\r\r\r\r\r\r对于已经授权本APP独家使用并提供给本站资料的版权所有的文章、图片等资料如需转载使用需取得本站和版权所有人的同意。本APP所刊发、转载的文章其版权均归原作者所有如其他媒体、网站或个人从本网下载使用请在转载有关文章时务必尊重该文章的著作权保留本网注明的“稿件来源”并自负版权等法律责任';
const disclaimerText1 =
'\r\r\r\r\r\r本APP属于个人的非赢利性开源项目以供开源社区使用凡本APP转载的所有的文章 、图片、音频、视频文件等资料的版权归版权所有人所有本APP采用的非本站原创文章及图片等内容无法一一和版权者联系如果本网所选内容的文章作者及编辑认为其作品不宜上网供大家浏览或不应无偿使用请及时用电子邮件或电话通知我们以迅速采取适当措施避免给双方造成不必要的经济损失';
const disclaimerText2 =
'\n\r\r\r\r\r\r对于已经授权本APP独家使用并提供给本站资料的版权所有人的文章、图片等资料如需转载使用需取得本站和版权所有人的同意。本APP所刊发、转载的文章其版权均归原作者所有如其他媒体、网站或个人从本网下载使用请在转载有关文章时务必尊重该文章的著作权保留本网注明的“稿件来源”并自负版权等法律责任。';
class DisclaimerMsg extends StatefulWidget {
final State pWidget;
DisclaimerMsg({ Key key, this.pWidget }) : super(key: key);
DisclaimerMsg({Key key, this.pWidget}) : super(key: key);
DisclaimerMsgState createState() => DisclaimerMsgState();
}
class DisclaimerMsgState extends State<DisclaimerMsg> {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Future<bool> _unKnow;
var _valBool = false;
var _page;
//CollectionControlModel _collectionControl = new CollectionControlModel();
//List<CollectionGeneral> _collectionList = [];
// void init(BuildContext context) {
// Toast.show(context: context, message: "👉 APP免责声明",cb:showAlertDialog);
// }
var _readed = false;
//SharedPreferences 存储结果
void refs(bool value) async {
final SharedPreferences prefs = await _prefs;
final bool unKnow = value;
if (mounted) {
setState(() {
_unKnow = prefs.setBool("disclaimer::Boolean", unKnow).then((bool success) {
return unKnow;
});
});
}
}
@override
void initState() {
super.initState();
// _collectionList.clear();
// _collectionControl.getAllCollection().then((resultList) {
// resultList.forEach((item) {
// _collectionList.add(item);
// print('=============db=========${item}');
// });
// });
_page = widget.pWidget;
}
void refs(bool value){
if(this.mounted){
setState(() {
_valBool=value;
_page.save(value);
});
// _collectionControl
// .insert(CollectionGeneral(key: 'disclaimer', values: value.toString()))
// .then((result) {
// print('result2====${result}');
// }
// );
}
//获取SharedPreferences 存储结果
_unKnow = _prefs.then((SharedPreferences prefs) {
return (prefs.getBool('disclaimer::Boolean') ?? false);
});
_unKnow.then((bool value) {
_valBool = value;
_readed = value;
});
}
void showAlertDialog(BuildContext context) {
// new Future.delayed(Duration(seconds: 5)).then((value) {
// Navigator.of(context).pop();
// });
showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
//title: Text('免责声明'),
content:SingleChildScrollView(
child: ListBody(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(5.0, 5.0, 10.0, 10.0),
//width: 100,
height: 35,
child: Text('免责声明',style:TextStyle(fontSize: 18,fontWeight:FontWeight.w700 )),
decoration: BoxDecoration(
//color: Colors.blue,
image: DecorationImage(
fit: BoxFit.fitWidth,
image: AssetImage('assets/images/paimaiLogo.png')
),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
//alignment: Alignment.bottomRight,
)
),
SizedBox(height:20),
Text(disclaimerText1),
Text(disclaimerText2),
],
),
),
shape:RoundedRectangleBorder(borderRadius: new BorderRadius.circular(20.0)), // 圆角
actions: <Widget>[
Container(
width: 270,
alignment: Alignment.centerLeft,
padding: new EdgeInsets.fromLTRB(0.0, 0.0, 30.0, 0.0),
child:
Row(
mainAxisAlignment:MainAxisAlignment.spaceAround,
//crossAxisAlignment:CrossAxisAlignment.start,
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Row(
mainAxisAlignment:MainAxisAlignment.center,
children: <Widget>[
Checkbox(
activeColor: Theme.of(context).primaryColor,
tristate:false,
value: _valBool,
onChanged: (bool bol) {
refs(bol);
Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs
showAlertDialog(context); //here i call the same function
}
),
Text('不再自动提示',style:TextStyle(fontSize: 14)),
],
),
new Flexible(
flex: 1,
child: Container(width: 100,)
),
FlatButton(
child: Text('知道了',style:TextStyle(fontSize: 16,color: Colors.white)),
color: Theme.of(context).primaryColor,
onPressed: () {
Navigator.of(context).pop();
},
),
]
// SizedBox(
// width:150,
// height:55,
// child: CheckboxListTile(
// title: Text('不再显示',style:TextStyle(fontSize: 14)),
// controlAffinity: ListTileControlAffinity.leading,
// activeColor: Colors.red,
// value: _valBool,
// onChanged: (bool value) {
// refs(value);
// Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs
// showAlertDialog(context); //here i call the same function
// }
// )
// //secondary: const Icon(Icons.hourglass_empty),
// ),
// Checkbox(
// activeColor: Colors.red,
// tristate:false,
// value: _valBool,
// onChanged: (bool bol) {
// refs(bol);
// Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs
// showAlertDialog(context); //here i call the same function
// }
// ),
// Text('不再显示',style:TextStyle(fontSize: 14)),
// FlatButton(
// child: Text('知道了',style:TextStyle(fontSize: 16,color: Colors.green)),
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// ],
Container(
padding: EdgeInsets.fromLTRB(5.0, 5.0, 10.0, 10.0),
//width: 100,
height: 35,
child: Text('免责声明',
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w700)),
decoration: BoxDecoration(
//color: Colors.blue,
image: DecorationImage(
fit: BoxFit.fitWidth,
image: AssetImage('assets/images/paimaiLogo.png')),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
//alignment: Alignment.bottomRight,
)),
SizedBox(height: 20),
Text(disclaimerText1),
Text(disclaimerText2),
],
),
),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(20.0)), // 圆角
actions: <Widget>[
new Container(
width: 250,
child: _create(),
)
)],
],
);
},
);
}
Widget build(BuildContext context) {
return new GestureDetector(
onTap: () {
showAlertDialog(context);
},
child: Stack(
//alignment: const Alignment(1.6, 1.6),
children: [
new Container(
width:90.0,
alignment: Alignment.center,
decoration: new BoxDecoration(
borderRadius:new BorderRadius.horizontal(right: Radius.circular(10)),
color: Colors.black45,
),
child: new Text(
'🔔 免责声明',
style: new TextStyle(
fontSize: 14.0,
//fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
)
);
}
Widget build2(BuildContext context) {
return Container(
padding: new EdgeInsets.all(0.0),
alignment:Alignment.centerRight,
child:FlatButton(
//padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child: new Text(
'👉 APP免责声明',
style: new TextStyle(
fontSize: 12.0, //textsize
color: Colors.black54, // textcolor
),
),
//color: Theme.of(context).accentColor,
color: Theme.of(context).accentColor,
//elevation: 0.0,//shadow
//splashColor: Colors.blueGrey,
Row _create() {
//已读
if (_readed) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Text('已阅读知晓',
style: TextStyle(fontSize: 16, color: Colors.white)),
//可点击
color: Theme.of(context).primaryColor,
onPressed: () {
showAlertDialog(context);
//Toast.show(context: context, message: "👉 APP免责声明",cb:showAlertDialog);
})
);
}
}
Navigator.of(context).pop();
},
),
SizedBox(
width: 10.0,
)
],
);
}
class Toast {
static void show({@required BuildContext context, @required String message,Function cb}) {
//创建一个OverlayEntry对象
OverlayEntry overlayEntry = new OverlayEntry(builder: (context) {
return new Positioned(
top: MediaQuery.of(context).size.height * 0.12,
right:5.0,
child:RaisedButton(
padding: new EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0),
child: new Text(
'👉 APP免责声明',
style: new TextStyle(
fontSize: 14.0, //textsize
color: Colors.black54, // textcolor
//第一次读取
return Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
//crossAxisAlignment:CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Checkbox(
activeColor: Theme.of(context).primaryColor,
tristate: false,
value: _valBool,
onChanged: (bool bol) {
if(mounted) {
setState(() {
_valBool = bol;
});
}
Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs
showAlertDialog(context); //here i call the same function
}),
Text('不再自动提示', style: TextStyle(fontSize: 14)),
],
),
FlatButton(
child: Text('知道了',
style: TextStyle(fontSize: 16, color: Colors.white)),
//可点击
color: _valBool
? Theme.of(context).primaryColor
: Theme.of(context).primaryColor.withAlpha(800),
onPressed: () {
// if (_valBool) {
refs(_valBool);
Navigator.of(context).pop();
// }
},
),
]);
}
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
showAlertDialog(context);
},
child: Stack(
//alignment: const Alignment(1.6, 1.6),
children: [
Container(
width: 90.0,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius:
BorderRadius.horizontal(right: Radius.circular(10)),
color: Colors.black45,
),
child: Text(
'🔔 免责声明',
style: TextStyle(
fontSize: 14.0,
//fontWeight: FontWeight.bold,
color: Colors.white,
),
),
//color: Theme.of(context).accentColor,
color: Colors.red,
//elevation: 0.0,//shadow
//splashColor: Colors.blueGrey,
onPressed: () {
if(cb is Function){
cb(context);
}
})
);
});
//往Overlay中插入插入OverlayEntry
Overlay.of(context).insert(overlayEntry);
new Future.delayed(Duration(seconds: 2)).then((value) {
//overlayEntry.remove();
});
),
],
));
}
}
}

View File

@ -0,0 +1,81 @@
/// @Author: 一凨
/// @Date: 2019-01-14 11:42:32
/// @Last Modified by: 一凨
/// @Last Modified time: 2019-01-14 14:42:00
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/example_code_parser.dart';
import 'package:flutter_go/utils/syntax_highlighter.dart';
class FullScreenCodeDialog extends StatefulWidget {
const FullScreenCodeDialog({this.filePath});
final String filePath;
_FullScreenCodeDialogState createState() => _FullScreenCodeDialogState();
}
class _FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
String _exampleCode;
@override
void didChangeDependencies() {
print('widget.filePath=======${widget.filePath}');
getExampleCode(context,'${widget.filePath}', DefaultAssetBundle.of(context))
.then<void>((String code) {
if (mounted) {
setState(() {
_exampleCode = code ?? 'Example code not found';
});
}
});
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
final SyntaxHighlighterStyle style =
Theme.of(context).brightness == Brightness.dark
? SyntaxHighlighterStyle.darkThemeStyle()
: SyntaxHighlighterStyle.lightThemeStyle();
Widget body;
if (_exampleCode == null) {
body = const Center(child: CircularProgressIndicator());
} else {
Widget _codeWidget;
try{
DartSyntaxHighlighter(style).format(_exampleCode);
_codeWidget = RichText(
text: TextSpan(
style: const TextStyle(fontFamily: 'monospace', fontSize: 10.0),
children: <TextSpan>[
DartSyntaxHighlighter(style).format(_exampleCode)
],),
);
}catch (err){
_codeWidget = Text(_exampleCode);
}
body = SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: _codeWidget,
),
);
}
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(
Icons.clear,
semanticLabel: 'Close',
),
onPressed: () {
Navigator.pop(context);
}),
title: const Text('Example code'),
),
body: body);
}
}

View File

@ -1,5 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../model/story.dart';
class HomeBanner extends StatefulWidget {

View File

@ -1,11 +1,12 @@
/**
* Created with Android Studio.
* User: 一晟
* Date: 2019/1/4
* Time: 上午1:16
* email: zhu.yan@alibaba-inc.com
* tartget: FlatButton 的示例
*/
/// Created with Android Studio.
/// User: 一晟
/// Date: 2019/1/4
/// Time: 上午1:16
/// email: zhu.yan@alibaba-inc.com
/// target: ListRefresh 的示例
import 'dart:async';
import 'package:flutter/material.dart';
class ListRefresh extends StatefulWidget {
@ -40,9 +41,7 @@ class _ListRefreshState extends State<ListRefresh> {
});
}
/*
* 回弹效果
* */
// 回弹效果
backElasticEffect() {
// double edge = 50.0;
// double offsetFromBottom = _scrollController.position.maxScrollExtent - _scrollController.position.pixels;
@ -54,13 +53,13 @@ class _ListRefreshState extends State<ListRefresh> {
// }
}
/*
* list探底执行的具体事件
* */
// list探底执行的具体事件
Future _getMoreData() async {
if (!isLoading && _hasMore) {
// 如果上一次异步请求数据完成 同时有数据可以加载
setState(() => isLoading = true);
if (mounted) {
setState(() => isLoading = true);
}
//if(_hasMore){ // 还有数据可以拉新
List newEntries = await mokeHttpRequest();
//if (newEntries.isEmpty) {
@ -79,9 +78,7 @@ class _ListRefreshState extends State<ListRefresh> {
}
}
/*
* 伪装吐出新数据
* */
// 伪装吐出新数据
Future<List> mokeHttpRequest() async {
if (widget.requestApi is Function) {
final listObj = await widget.requestApi({'pageIndex': _pageIndex});
@ -94,11 +91,8 @@ class _ListRefreshState extends State<ListRefresh> {
});
}
}
/*
* 下拉加载的事件清空之前list内容取前X个
* 其实就是列表重置
* */
// 下拉加载的事件清空之前list内容取前X个
// 其实就是列表重置
Future<Null> _handleRefresh() async {
List newEntries = await mokeHttpRequest();
if (this.mounted) {
@ -112,9 +106,7 @@ class _ListRefreshState extends State<ListRefresh> {
}
}
/*
* 加载中的提示
* */
// 加载中的提示
Widget _buildLoadText() {
return Container(
child: Padding(
@ -125,9 +117,7 @@ class _ListRefreshState extends State<ListRefresh> {
));
}
/*
* 上提加载loading的widget,如果数据到达极限,显示没有更多
* */
// 上提加载loading的widget,如果数据到达极限,显示没有更多
Widget _buildProgressIndicator() {
if (_hasMore) {
return new Padding(

View File

@ -0,0 +1,53 @@
/// @Author: 一凨
/// @Date: 2019-01-14 17:53:54
/// @Last Modified by: 一凨
/// @Last Modified time: 2019-01-14 17:57:51
import 'package:flutter/material.dart';
import '../routers/application.dart';
import '../routers/routers.dart';
import 'dart:core';
class ListViewItem extends StatelessWidget {
final String itemUrl;
final String itemTitle;
final String data;
const ListViewItem({Key key, this.itemUrl, this.itemTitle, this.data})
: super(key: key);
@override
Widget build(BuildContext context) {
return Card(
color: Colors.white,
elevation: 4.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: ListTile(
onTap: () {
// _launchURL(itemUrl, context);
Application.router.navigateTo(context, '${Routes.webViewPage}?title=${Uri.encodeComponent(itemTitle)}&url=${Uri.encodeComponent(itemUrl)}');
},
title: Padding(
child: Text(
itemTitle,
style: TextStyle(color: Colors.black, fontSize: 15.0),
),
padding: EdgeInsets.only(top: 10.0),
),
subtitle: Row(
children: <Widget>[
Padding(
child: Text(data,
style: TextStyle(color: Colors.black54, fontSize: 10.0)),
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
)
],
),
trailing:
Icon(Icons.keyboard_arrow_right, color: Colors.grey, size: 30.0),
),
);
}
}

View File

@ -1,7 +1,8 @@
import 'package:flutter_markdown/flutter_markdown.dart' as md;
import '../common/high_light_code.dart';
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/high_light_code.dart';
/// 使用方法
/// MarkdownBody(markdown)
final hightlighter = new HighLight();

View File

@ -3,9 +3,10 @@
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import './home_banner.dart';
import '../model/story.dart';
import 'package:url_launcher/url_launcher.dart';
class Pagination extends StatelessWidget {
static final String routeName = '/material/page-selector';

View File

@ -1,6 +1,11 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:meta/meta.dart';
import 'package:flutter_go/resources/widget_name_to_icon.dart';
import 'package:flutter_go/routers/application.dart';
import '../model/search_history.dart';
typedef String FormFieldFormatter<T>(T v);
typedef bool MaterialSearchFilter<T>(T v, String c);
@ -18,13 +23,14 @@ class MaterialSearchResult<T> extends StatelessWidget {
this.onTap
}) : super(key: key);
final T value;
final String value;
final VoidCallback onTap;
final String text;
final IconData icon;
@override
Widget build(BuildContext context) {
return new InkWell(
onTap: this.onTap,
child: new Container(
@ -32,8 +38,8 @@ class MaterialSearchResult<T> extends StatelessWidget {
padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
child: new Row(
children: <Widget>[
new Container(width: 30.0, child: new Icon(icon)) ?? null,
new Expanded(child: new Text(text, style: Theme.of(context).textTheme.subhead)),
new Container(width: 30.0, margin: EdgeInsets.only(right: 10), child: new Icon(icon)) ?? null,
new Expanded(child: new Text(value, style: Theme.of(context).textTheme.subhead)),
new Text(text, style: Theme.of(context).textTheme.subhead)
],
),
@ -407,11 +413,9 @@ class History extends StatefulWidget {
_History createState() => _History();
}
/*
* AppBar 默认的实例,有状态
* */
// AppBar 默认的实例,有状态
class _History extends State<History> {
SearchHistoryList searchHistoryList = new SearchHistoryList();
@override
void initState() {
@ -422,11 +426,68 @@ class _History extends State<History> {
void dispose() {
super.dispose();
}
buildChips(BuildContext context) {
List<Widget> list = [];
List<SearchHistory> historyList = searchHistoryList.getList();
print("historyList> $historyList");
Color bgColor = Theme.of(context).primaryColor;
historyList.forEach((SearchHistory value) {
Widget icon = CircleAvatar(
backgroundColor: bgColor,
child: Text(
value.name.substring(0, 1),
style: TextStyle(color: Colors.white),
),
);
if (WidgetName2Icon.icons[value.name] != null) {
icon = Icon(WidgetName2Icon.icons[value.name], size: 25);
}
list.add(
InkWell(
onTap: () {
Application.router.navigateTo(context, "${value.targetRouter}", transition: TransitionType.inFromRight);
},
child: Chip(
avatar: icon,
label: Text("${value.name}"),
),
)
);
});
return list;
}
@override
Widget build(BuildContext context) {
return new Center(
child: Text('这是一个即将完善的历史记录的面板'),
List<Widget> childList = buildChips(context);
if (childList.length == 0) {
return Center(
child: Text("当前历史面板为空"),
);
}
return Column(
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.fromLTRB(12.0, 12, 12, 0),
child: InkWell(
onLongPress: () {
searchHistoryList.clear();
},
child: Text('历史搜索'),
),
),
Container(
padding: EdgeInsets.only(left: 10),
alignment: Alignment.topLeft,
child: Wrap(
spacing: 6.0, // gap between adjacent chips
runSpacing: 0.0, // gap between lines
children: childList
),
)
],
);
}
}

View File

@ -0,0 +1,200 @@
/// @author Nealyang
/// 新widget详情页模板
import 'dart:core';
import 'package:flutter/material.dart';
import '../routers/application.dart';
import '../routers/routers.dart';
import '../components/markdown.dart';
import '../model/collection.dart';
import '../widgets/index.dart';
import '../event/event_bus.dart';
import '../event/event_model.dart';
class WidgetDemo extends StatefulWidget {
final List<dynamic> contentList;
final String docUrl;
final String title;
final String codeUrl;
final Widget bottomNaviBar;
WidgetDemo(
{Key key,
@required this.title,
@required this.contentList,
@required this.codeUrl,
@required this.docUrl,
this.bottomNaviBar})
: super(key: key);
_WidgetDemoState createState() => _WidgetDemoState();
}
class _WidgetDemoState extends State<WidgetDemo> {
bool _hasCollected = false;
CollectionControlModel _collectionControl = new CollectionControlModel();
var _collectionIcons;
List widgetDemosList = new WidgetDemoList().getDemos();
String _router = '';
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
List<Widget> _buildContent() {
List<Widget> _list = [
SizedBox(
height: 10.0,
),
];
widget.contentList.forEach((item) {
if (item.runtimeType == String) {
_list.add(MarkdownBody(item));
_list.add(
SizedBox(
height: 20.0,
),
);
} else {
_list.add(item);
}
});
return _list;
}
@override
void initState() {
super.initState();
_collectionControl.getRouterByName(widget.title).then((list) {
widgetDemosList.forEach((item) {
if (item.name == widget.title) {
_router = item.routerName;
}
});
if (this.mounted) {
setState(() {
_hasCollected = list.length > 0;
});
}
});
}
// 点击收藏按钮
_getCollection() {
if (_hasCollected) {
// 删除操作
_collectionControl.deleteByName(widget.title).then((result) {
if (result > 0 && this.mounted) {
setState(() {
_hasCollected = false;
});
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('已取消收藏')));
if (ApplicationEvent.event != null) {
ApplicationEvent.event
.fire(CollectionEvent(widget.title, _router, true));
}
return;
}
print('删除错误');
});
} else {
// 插入操作
_collectionControl
.insert(Collection(name: widget.title, router: _router))
.then((result) {
if (this.mounted) {
setState(() {
_hasCollected = true;
});
if (ApplicationEvent.event != null) {
ApplicationEvent.event
.fire(CollectionEvent(widget.title, _router, false));
}
_scaffoldKey.currentState
.showSnackBar(SnackBar(content: Text('收藏成功')));
}
});
}
}
void _selectValue(value) {
if (value == 'doc') {
// _launchURL(widget.docUrl);
Application.router.navigateTo(context,
'${Routes.webViewPage}?title=${Uri.encodeComponent(widget.title)} Doc&&url=${Uri.encodeComponent(widget.docUrl)}');
} else if (value == 'code') {
Application.router.navigateTo(context,
'${Routes.codeView}?filePath=${Uri.encodeComponent(widget.codeUrl)}');
}
}
@override
Widget build(BuildContext context) {
if (_hasCollected) {
_collectionIcons = Icons.favorite;
} else {
_collectionIcons = Icons.favorite_border;
}
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
new IconButton(
tooltip: 'goBack home',
onPressed: () {
Navigator.popUntil(context, ModalRoute.withName('/'));
},
icon: Icon(Icons.home),
),
new IconButton(
tooltip: 'collection',
onPressed: _getCollection,
icon: Icon(_collectionIcons),
),
PopupMenuButton<String>(
onSelected: _selectValue,
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'doc',
child: ListTile(
leading: Icon(
Icons.library_books,
size: 22.0,
),
title: Text('查看文档'),
),
),
const PopupMenuDivider(),
const PopupMenuItem<String>(
value: 'code',
child: ListTile(
leading: Icon(
Icons.code,
size: 22.0,
),
title: Text('查看Demo'),
),
),
],
),
],
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
child: ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(0.0),
children: <Widget>[
Column(
children: _buildContent(),
),
],
),
),
bottomNavigationBar:
(widget.bottomNaviBar is Widget) ? widget.bottomNaviBar : null);
}
}

View File

@ -1,9 +1,9 @@
/**
* @author 一凨
*/
/// @author 一凨
import 'package:flutter/material.dart';
import '../common/style.dart';
import '../common/widget_name_to_icon.dart';
import 'package:flutter_go/utils/style.dart';
import 'package:flutter_go/resources/widget_name_to_icon.dart';
String _widgetName;
@ -13,9 +13,15 @@ class WidgetItem extends StatelessWidget {
final int index; //用于计算border
final int totalCount;
final int rowLength;
final String textSize;
WidgetItem(
{this.title, this.onTap, this.index, this.totalCount, this.rowLength});
{this.title,
this.onTap,
this.index,
this.totalCount,
this.rowLength,
this.textSize});
Border _buildBorder(context) {
Border _border;
@ -64,6 +70,9 @@ class WidgetItem extends StatelessWidget {
Icons.crop,
);
}
final textStyle = (textSize == 'middle')
? TextStyle(fontSize: 13.8, fontFamily: 'MediumItalic')
: TextStyle(fontSize: 16.0);
return InkWell(
onTap: onTap,
child: Container(
@ -80,7 +89,7 @@ class WidgetItem extends StatelessWidget {
SizedBox(
height: 8.0,
),
Text(_widgetName),
Text(_widgetName, style: textStyle),
],
),
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import './widget_item.dart';
import '../routers/application.dart';
import '../widgets/index.dart';
@ -7,6 +8,7 @@ class WidgetItemContainer extends StatelessWidget {
final int columnCount; //一行几个
final List<dynamic> categories;
final bool isWidgetPoint;
// 所有的可用demos;
final List widgetDemosList = new WidgetDemoList().getDemos();
@ -41,15 +43,16 @@ class WidgetItemContainer extends StatelessWidget {
targetRouter = item.routerName;
}
});
Application.router.navigateTo(context, "$targetRouter");
Application.router.navigateTo(context, "$targetRouter", transition: TransitionType.inFromRight);
} else {
Application.router
.navigateTo(context, "/category/${item.name}");
.navigateTo(context, "/category/${item.name}", transition: TransitionType.inFromRight);
}
},
index: addI,
totalCount: length,
rowLength: columnCount,
textSize: isWidgetPoint ? 'middle' : 'small',
),
),
);

5
lib/event/event_bus.dart Normal file
View File

@ -0,0 +1,5 @@
import 'package:event_bus/event_bus.dart';
class ApplicationEvent{
static EventBus event;
}

View File

@ -0,0 +1,7 @@
class CollectionEvent{
final String widgetName;
final String router;
final bool isRemove;
// token uid...
CollectionEvent(this.widgetName,this.router,this.isRemove);
}

View File

@ -1,27 +1,37 @@
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/rendering.dart';
import 'views/first_page.dart';
import 'views/widget_page.dart';
import 'views/fourth_page.dart';
import 'views/collection_page.dart';
import 'routers/routers.dart';
import 'routers/application.dart';
import 'common/provider.dart';
import 'model/widget.dart';
import './widgets/index.dart';
import 'package:flutter_go/components/search_input.dart';
import 'package:flutter_go/utils/provider.dart';
import 'package:flutter_go/utils/shared_preferences.dart';
import 'package:flutter_go/views/first_page/home.dart';
import 'package:flutter_go/model/search_history.dart';
//import 'views/welcome_page/index.dart';
const int ThemeColor = 0xFFC91B3A;
SpUtil sp;
var db;
class MyApp extends StatelessWidget {
MyApp() {
MyApp() {
final router = new Router();
Routes.configureRoutes(router);
Application.router = router;
}
showWelcomePage() {
// 暂时关掉欢迎介绍
return AppPage();
// bool showWelcome = sp.getBool(SharedPreferencesKeys.showWelcome);
// if (showWelcome == null || showWelcome == true) {
// return WelcomePage();
// } else {
// return AppPage();
// }
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
@ -39,158 +49,20 @@ class MyApp extends StatelessWidget {
size: 35.0,
),
),
home: new MyHomePage(),
home: new Scaffold(
body: showWelcomePage()
),
onGenerateRoute: Application.router.generator,
);
}
}
var db;
void main() async {
final provider = new Provider();
await provider.init(true);
sp = await SpUtil.getInstance();
new SearchHistoryList(sp);
db = Provider.db;
runApp(new MyApp());
}
class MyHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
WidgetControlModel widgetControl = new WidgetControlModel();
TabController controller;
bool isSearch = false;
String data = '';
String data2ThirdPage = '这是传给ThirdPage的值';
String appBarTitle = tabData[0]['text'];
static List tabData = [
{'text': '业界动态', 'icon': new Icon(Icons.language)},
{'text': 'WIDGET', 'icon': new Icon(Icons.extension)},
{'text': '组件收藏', 'icon': new Icon(Icons.star)},
{'text': '关于手册', 'icon': new Icon(Icons.favorite)}
];
List<Widget> myTabs = [];
@override
void initState() {
super.initState();
controller = new TabController(
initialIndex: 0, vsync: this, length: 4); // 这里的length 决定有多少个底导 submenus
for (int i = 0; i < tabData.length; i++) {
myTabs.add(new Tab(text: tabData[i]['text'], icon: tabData[i]['icon']));
}
controller.addListener(() {
if (controller.indexIsChanging) {
_onTabChange();
}
});
Application.controller = controller;
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
void onWidgetTap(WidgetPoint widgetPoint, BuildContext context) {
List widgetDemosList = new WidgetDemoList().getDemos();
String targetName = widgetPoint.name;
String targetRouter = '/category/error/404';
widgetDemosList.forEach((item) {
if (item.name == targetName) {
targetRouter = item.routerName;
}
});
Application.router.navigateTo(context, "$targetRouter");
}
Widget buildSearchInput(BuildContext context) {
return new SearchInput((value) async {
if (value != '') {
List<WidgetPoint> list = await widgetControl.search(value);
return list
.map((item) => new MaterialSearchResult<String>(
value: item.name,
text: item.name,
onTap: () {
onWidgetTap(item, context);
},
))
.toList();
} else {
return null;
}
}, (value) {}, () {});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: buildSearchInput(context)),
body: new TabBarView(controller: controller, children: <Widget>[
new FirstPage(),
new WidgetPage(db),
new CollectionPage(),
new FourthPage()
]),
bottomNavigationBar: Material(
color: const Color(0xFFF0EEEF), //底部导航栏主题颜色
child: SafeArea(
child: Container(
height: 65.0,
decoration: BoxDecoration(
color: const Color(0xFFF0F0F0),
boxShadow: <BoxShadow>[
BoxShadow(
color: const Color(0xFFd0d0d0),
blurRadius: 3.0,
spreadRadius: 2.0,
offset: Offset(-1.0, -1.0),
),
],
),
child: TabBar(
controller: controller,
indicatorColor: Theme.of(context).primaryColor, //tab标签的下划线颜色
// labelColor: const Color(0xFF000000),
indicatorWeight: 3.0,
labelColor: Theme.of(context).primaryColor,
unselectedLabelColor: const Color(0xFF8E8E8E),
tabs: <Tab>[
Tab(text: '业界动态', icon: Icon(Icons.language)),
Tab(text: '组件', icon: Icon(Icons.extension)),
Tab(text: '组件收藏', icon: Icon(Icons.favorite)),
Tab(text: '关于手册', icon: Icon(Icons.line_weight)),
],
),
),
),
),
);
}
void _onTabChange() {
if (this.mounted) {
this.setState(() {
appBarTitle = tabData[controller.index]['text'];
});
}
}
// void _onDataChange(val) {
// if (this.mounted) {
// setState(() {
// data = val;
// });
// }
// }
}

View File

@ -1,6 +1,5 @@
import 'package:sqflite/sqflite.dart';
class BaseModel{
Database db;
final String table = '';

View File

@ -1,6 +1,7 @@
import 'dart:async';
import '../common/sql.dart';
import 'package:flutter_go/utils/sql.dart';
abstract class CatInterface{
int get id;

View File

@ -1,11 +1,11 @@
/*
* @Author: 一凨
* @Date: 2019-01-07 16:24:42
* @Last Modified by: 一凨
* @Last Modified time: 2019-01-08 17:37:42
*/
/// @Author: 一凨
/// @Date: 2019-01-07 16:24:42
/// @Last Modified by: 一凨
/// @Last Modified time: 2019-01-08 17:37:42
import 'dart:async';
import '../common/sql.dart';
import 'package:flutter_go/utils/sql.dart';
abstract class CollectionInterface {
String get name;

View File

@ -0,0 +1,101 @@
///
/// Created with Android Studio.
/// User: 三帆
/// Date: 18/02/2019
/// Time: 14:19
/// email: sanfan.hx@alibaba-inc.com
/// target: 搜索WidgetDemo中的历史记录model
///
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_go/utils/shared_preferences.dart';
class SearchHistory {
final String name;
final String targetRouter;
SearchHistory({@required this.name, @required this.targetRouter});
}
class SearchHistoryList {
static SpUtil _sp;
static SearchHistoryList _instance;
static List<SearchHistory> _searchHistoryList = [];
static SearchHistoryList _getInstance(SpUtil sp) {
if (_instance == null) {
_sp = sp;
String json = sp.get(SharedPreferencesKeys.searchHistory);
_instance = new SearchHistoryList.fromJSON(json);
}
return _instance;
}
factory SearchHistoryList([SpUtil sp]) {
if (sp == null && _instance == null) {
print(new ArgumentError(
['SearchHistoryList need instantiatied SpUtil at first timte ']));
}
return _getInstance(sp);
}
// List<SearchHistory> _searchHistoryList = [];
// 存放的最大数量
int _count = 10;
SearchHistoryList.fromJSON(String jsonData) {
_searchHistoryList = [];
if (jsonData == null) {
return;
}
List jsonList = json.decode(jsonData);
jsonList.forEach((value) {
_searchHistoryList.add(SearchHistory(
name: value['name'], targetRouter: value['targetRouter']));
});
}
List<SearchHistory> getList() {
return _searchHistoryList;
}
clear() {
_sp.remove(SharedPreferencesKeys.searchHistory);
_searchHistoryList = [];
}
save() {
_sp.putString(SharedPreferencesKeys.searchHistory, this.toJson());
}
add(SearchHistory item) {
print("_searchHistoryList> ${_searchHistoryList.length}");
for (SearchHistory value in _searchHistoryList) {
if (value.name == item.name) {
return;
}
}
if (_searchHistoryList.length > _count) {
_searchHistoryList.removeAt(0);
}
_searchHistoryList.add(item);
save();
}
toJson() {
List<Map<String, String>> jsonList = [];
_searchHistoryList.forEach((SearchHistory value) {
jsonList.add({'name': value.name, 'targetRouter': value.targetRouter});
});
return json.encode(jsonList);
}
@override
String toString() {
return this.toJson();
}
}

View File

@ -1,8 +1,10 @@
import 'dart:async';
import '../common/sql.dart';
import "package:flutter/material.dart";
import 'package:flutter_go/utils/sql.dart';
abstract class WidgetInterface {
int get id;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,38 @@
// Created with Android Studio.
// User: 三帆
// Date: 31/01/2019
// Time: 18:13
// email: sanfan.hx@alibaba-inc.com
// target: xxx
//
//enum DateType {
// Int,
// Double,
// Bool,
// String,
// Dynamic
//}
//class spKey {
// String name;
// DateType type;
//
// spKey({this.name, this.type});
//}
class SharedPreferencesKeys {
/// boolean
/// 用于欢迎页面. 只有第一次访问才会显示. 或者手动将这个值设为false
static String showWelcome = 'loginWelcone';
/// json
/// 用于存放搜索页的搜索数据.
/// [{
/// name: 'name'
///
/// }]
static String searchHistory = 'searchHistory';
}

View File

@ -0,0 +1,171 @@
import 'package:flutter/material.dart';
class WidgetName2Icon {
static Map<String,dynamic> icons = {
"Element":Icons.explicit,
"Components":Icons.extension,
"Themes":Icons.filter_b_and_w,
"Form":Icons.table_chart,
"Frame":Icons.aspect_ratio,
"Media":Icons.subscriptions,
"Input":Icons.input,
"TextField":Icons.text_fields,
"Checkbox":Icons.check_box,
"CheckboxListTile":Icons.playlist_add_check,
"Button":Icons.aspect_ratio,
"FlatButton":Icons.outlined_flag,
"RaisedButton":Icons.picture_in_picture_alt,
"IconButton":Icons.import_contacts,
"PopupMenuButton":Icons.power_input,
"FloatingActionButton":Icons.flash_off,
"RawMaterialButton":Icons.rowing,
"DropdownButton":Icons.drag_handle,
"OutlineButton":Icons.done_outline,
"Text":Icons.text_format,
"RichText":Icons.text_rotation_angleup,
"Radio":Icons.radio_button_checked,
"RadioListTile":Icons.list,
"Slider":Icons.slideshow,
"SliderTheme":Icons.theaters,
"SliderComponentShape":Icons.format_shapes,
"SliderThemeData":Icons.data_usage,
"Switch":Icons.switch_camera,
"SwitchListTile":Icons.switch_video,
"AnimatedSwitcher":Icons.airplanemode_active,
"Align":Icons.format_align_left,
"Stack":Icons.storage,
"IndexedStack":Icons.star,
"Layout":Icons.layers,
"Row":Icons.recent_actors,
"Column":Icons.cloud_off,
"Container":Icons.edit_location,
"Center":Icons.gesture,
"Box":Icons.hdr_strong,
"ConstrainedBox":Icons.account_box,
"OverflowBox":Icons.email,
"DecoratedBox":Icons.settings_overscan,
"FittedBox":Icons.data_usage,
"LimitedBox":Icons.format_align_justify,
"RenderBox":Icons.error,
"RotateBox":Icons.navigate_next,
"SizedOverflowBox":Icons.undo,
"TextBox":Icons.wallpaper,
"UnconstrainedBox":Icons.account_box,
"Axis":Icons.access_alarm,
"MainAxis":Icons.add_circle,
"CrossAxis":Icons.dehaze,
"FlipAxis":Icons.zoom_out,
"Expanded":Icons.all_out,
"Spacing":Icons.crop_free,
"Padding":Icons.crop,
"SliverPadding":Icons.euro_symbol,
"AnimatedPadding":Icons.zoom_out_map,
"Table":Icons.table_chart,
"Image":Icons.image,
"AssetImage":Icons.image_aspect_ratio,
"DecorationImage":Icons.picture_in_picture,
"DecorationImagePainter":Icons.image,
"ExactAssetImage":Icons.assessment,
"FadeInImage":Icons.flip,
"FileImage":Icons.filter,
"NetworkImage":Icons.network_wifi,
"RawImage":Icons.text_rotation_down,
"PaintImage":Icons.format_paint,
"PrecacheImage":Icons.perm_camera_mic,
"MemoryImage":Icons.memory,
"Icon":Icons.event_available,
"ImageIcon":Icons.image,
"IconTheme":Icons.table_chart,
"IconData":Icons.date_range,
"IconThemeData":Icons.insert_comment,
"Canvas":Icons.edit,
"PainterPath":Icons.gesture,
"CircleProgressBarPainter":Icons.av_timer,
"PainterSketch":Icons.touch_app,
"Material":Icons.android,
"MaterialApp":Icons.android,
"MaterialButton":Icons.speaker,
"MaterialGap":Icons.view_week,
"MaterialSlice":Icons.format_list_numbered_rtl ,
"MaterialColor":Icons.color_lens,
"Cupertino":Icons.phone_iphone,
"Scroll":Icons.swap_vertical_circle,
"Tab":Icons.tab,
"Menu":Icons.menu,
"PopupMenuDivider":Icons.remove,
"PopupMenuEntry":Icons.menu,
"CheckedPopupMenuItem":Icons.playlist_add_check,
"DropdownMenuItem":Icons.playlist_play,
"Grid":Icons.grid_on,
"Scaffold":Icons.local_convenience_store,
"Dialog":Icons.add_alert,
"Bar":Icons.border_horizontal,
"Card":Icons.credit_card,
"Panel":Icons.video_label,
"Navigation":Icons.navigation,
"List":Icons.list,
"ScrollView":Icons.move_to_inbox,
"Scrollable":Icons.swap_vertical_circle,
"ScrollbarPainter":Icons.format_paint,
"ScrollMetrics":Icons.camera,
"ScrollPhysics":Icons.control_point_duplicate,
"BoxScrollView":Icons.inbox,
"Chip":Icons.sim_card,
"ChipTheme":Icons.sd_card,
"CustomScrollView":Icons.autorenew,
"NestedScrollView":Icons.panorama_fish_eye,
"ChipThemeData":Icons.sim_card_alert,
"ChoiceChip":Icons.insert_drive_file,
"FilterChip":Icons.note_add,
"InputChip":Icons.restore_page,
"RawChip":Icons.save,
"LinearProgressIndicator":Icons.trending_flat ,
"CircularProgressIndicator":Icons.rotate_left ,
"ExpansionPanel":Icons.view_stream,
"ExpansionPanelList":Icons.view_headline,
"BottomNavigationBar":Icons.call_to_action,
"ListView":Icons.view_list ,
"ListBody":Icons.list ,
"AnimatedList":Icons.format_line_spacing ,
"SliverAppBar":Icons.content_paste,
"AppBar":Icons.card_membership,
"BottomAppBar":Icons.call_to_action,
"BottomNavigationBarItem":Icons.crop_original,
"FlexibleSpaceBar":Icons.aspect_ratio,
"ButtonBar":Icons.branding_watermark,
"SnackBar":Icons.sms_failed,
"Progress":Icons.sync,
"Pick":Icons.event_note,
"DayPicker":Icons.calendar_today,
"MonthPicker":Icons.date_range,
"YearPicker":Icons.event_busy,
"ShowdatePicker":Icons.event,
"MaterialPageRoute":Icons.album,
"MaterialAccentColor":Icons.brush,
"SnackBarAction":Icons.assessment,
"TabBar":Icons.burst_mode,
"AlertDialog":Icons.sms_failed,
"AboutDialog":Icons.sms,
"SimpleDialog":Icons.message,
"ScaffoldState":Icons.local_bar,
"GridTile":Icons.apps,
"MergeableMaterialItem":Icons.view_list,
"CupertinoApp":Icons.face,
"CupertinoButton":Icons.crop_7_5,
"CupertinoColors":Icons.color_lens,
"CupertinoIcons":Icons.insert_emoticon,
"CupertinoNavigationBar":Icons.payment,
"CupertinoPageRoute":Icons.router,
"CupertinoPageScaffold":Icons.pages,
"CupertinoPicker":Icons.add_alarm,
"CupertinoPopupSurface":Icons.center_focus_weak,
"CupertinoScrollbar": Icons.fullscreen,
"CupertinoSlider": Icons.switch_camera,
"CupertinoSegmentedControl": Icons.business_center,
"CupertinoSliverNavigationBar": Icons.subtitles,
"CupertinoSwitch": Icons.radio_button_checked,
"CupertinoTabBar": Icons.tab,
"CupertinoTabScaffold": Icons.crop_original,
"CupertinoTabView": Icons.tablet,
"CupertinoTimerPicker": Icons.timer
};
}

View File

@ -1,10 +1,15 @@
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter_go/utils/shared_preferences.dart';
class Application {
static Router router;
static TabController controller;
static SpUtil sharePeferences;
static Map<String, String> github = {
'widgetsURL':'https://github.com/alibaba-paimai-frontend/flutter-common-widgets-app/tree/develop/lib/widgets/',
'widgetsURL':'https://github.com/alibaba/flutter-go/blob/develop/lib/widgets/',
//'develop':'https://github.com/alibaba-paimai-frontend/flutter-common-widgets-app/tree/develop/lib/widgets/',
//'master':'https://github.com/alibaba-paimai-frontend/flutter-common-widgets-app/tree/master/lib/widgets/'
};

View File

@ -1,9 +1,18 @@
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import '../views/category.dart';
import 'package:flutter_go/components/category.dart';
import '../widgets/404.dart';
import '../common/full_screen_code_dialog.dart';
import '../views/web_view_page.dart';
import 'package:flutter_go/components/full_screen_code_dialog.dart';
import 'package:flutter_go/views/web_page/web_view_page.dart';
import 'package:flutter_go/views/first_page/home.dart';
// app的首页
var homeHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return new AppPage();
},
);
var categoryHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {

View File

@ -1,11 +1,13 @@
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import '../widgets/index.dart';
import './router_handler.dart';
class Routes {
static String root = "/";
static String home = "/home";
static String widgetDemo = '/widget-demo';
static String codeView = '/code-view';
static String webViewPage = '/web-view-page';
@ -15,16 +17,16 @@ class Routes {
router.notFoundHandler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
});
router.define(home, handler: homeHandler);
router.define('/category/:type', handler: categoryHandler);
router.define('/category/error/404', handler: widgetNotFoundHandler);
router.define(codeView,handler:fullScreenCodeDialog);
router.define(webViewPage,handler:webViewPageHand);
widgetDemosList.forEach((demo) {
Handler handler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return demo.buildRouter(context);
widgetDemosList.forEach((demo) {
Handler handler = new Handler(
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
return demo.buildRouter(context);
});
router.define('${demo.routerName}', handler: handler);
});

View File

@ -0,0 +1,40 @@
/// @Author: 一凨
/// @Date: 2019-01-14 11:42:36
/// @Last Modified by: 一凨
/// @Last Modified time: 2019-01-14 16:53:11
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter_go/routers/application.dart';
Map<String, String> _exampleCode;
String _code;
void _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
Future<String> getExampleCode(context,String filePath, AssetBundle bundle) async {
if (_exampleCode == null) await _parseExampleCode(context,filePath, bundle);
return _code;
}
Future<void> _parseExampleCode(context,String filePath, AssetBundle bundle) async {
String code;
try {
code = await bundle.loadString('lib/widgets/$filePath');
} catch (err) {
Navigator.of(context).pop();
_launchURL(Application.github['widgetsURL'] + filePath);
}
_code = code;
}

View File

@ -0,0 +1,359 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:string_scanner/string_scanner.dart';
/// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle();
/// DartSyntaxHighlighter(style).format(source)
class SyntaxHighlighterStyle {
SyntaxHighlighterStyle({
this.baseStyle,
this.numberStyle,
this.commentStyle,
this.keywordStyle,
this.stringStyle,
this.punctuationStyle,
this.classStyle,
this.constantStyle
});
static SyntaxHighlighterStyle lightThemeStyle() {
return SyntaxHighlighterStyle(
baseStyle: const TextStyle(color: Color(0xFF000000)),
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
keywordStyle: const TextStyle(color: Color(0xFF9C27B0)),
stringStyle: const TextStyle(color: Color(0xFF43A047)),
punctuationStyle: const TextStyle(color: Color(0xFF000000)),
classStyle: const TextStyle(color: Color(0xFF512DA8)),
constantStyle: const TextStyle(color: Color(0xFF795548))
);
}
static SyntaxHighlighterStyle darkThemeStyle() {
return SyntaxHighlighterStyle(
baseStyle: const TextStyle(color: Color(0xFFFFFFFF)),
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
keywordStyle: const TextStyle(color: Color(0xFF80CBC4)),
stringStyle: const TextStyle(color: Color(0xFF009688)),
punctuationStyle: const TextStyle(color: Color(0xFFFFFFFF)),
classStyle: const TextStyle(color: Color(0xFF009688)),
constantStyle: const TextStyle(color: Color(0xFF795548))
);
}
final TextStyle baseStyle;
final TextStyle numberStyle;
final TextStyle commentStyle;
final TextStyle keywordStyle;
final TextStyle stringStyle;
final TextStyle punctuationStyle;
final TextStyle classStyle;
final TextStyle constantStyle;
}
abstract class Highlighter { // ignore: one_member_abstracts
TextSpan format(String src);
}
class DartSyntaxHighlighter extends Highlighter {
DartSyntaxHighlighter([this._style]) {
_spans = <_HighlightSpan>[];
_style ??= SyntaxHighlighterStyle.darkThemeStyle();
}
SyntaxHighlighterStyle _style;
static const List<String> _keywords = <String>[
'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch',
'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else',
'enum', 'export', 'external', 'extends', 'factory', 'false', 'final',
'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static',
'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var',
'void', 'while', 'with', 'yield'
];
static const List<String> _builtInTypes = <String>[
'int', 'double', 'num', 'bool'
];
String _src;
StringScanner _scanner;
List<_HighlightSpan> _spans;
@override
TextSpan format(String src) {
_src = src;
_scanner = StringScanner(_src);
if (_generateSpans()) {
// Successfully parsed the code
final List<TextSpan> formattedText = <TextSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
if (currentPosition != span.start)
formattedText.add(TextSpan(text: _src.substring(currentPosition, span.start)));
formattedText.add(TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src)));
currentPosition = span.end;
}
if (currentPosition != _src.length)
formattedText.add(TextSpan(text: _src.substring(currentPosition, _src.length)));
return TextSpan(style: _style.baseStyle, children: formattedText);
} else {
// Parsing failed, return with only basic formatting
return TextSpan(style: _style.baseStyle, text: src);
}
}
bool _generateSpans() {
int lastLoopPosition = _scanner.position;
while (!_scanner.isDone) {
// Skip White space
_scanner.scan(RegExp(r'\s+'));
// Block comments
if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
_spans.add(_HighlightSpan(
_HighlightType.comment,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Line comments
if (_scanner.scan('//')) {
final int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
if (_scanner.scan(RegExp(r'.*\n'))) {
endComment = _scanner.lastMatch.end - 1;
} else {
eof = true;
endComment = _src.length;
}
_spans.add(_HighlightSpan(
_HighlightType.comment,
startComment,
endComment
));
if (eof)
break;
continue;
}
// Raw r"String"
if (_scanner.scan(RegExp(r'r".*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Raw r'String'
if (_scanner.scan(RegExp(r"r'.*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline """String"""
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline '''String'''
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// "String"
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// 'String'
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Double
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Integer
if (_scanner.scan(RegExp(r'\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end)
);
continue;
}
// Punctuation
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
_spans.add(_HighlightSpan(
_HighlightType.punctuation,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Meta data
if (_scanner.scan(RegExp(r'@\w+'))) {
_spans.add(_HighlightSpan(
_HighlightType.keyword,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Words
if (_scanner.scan(RegExp(r'\w+'))) {
_HighlightType type;
String word = _scanner.lastMatch[0];
if (word.startsWith('_'))
word = word.substring(1);
if (_keywords.contains(word))
type = _HighlightType.keyword;
else if (_builtInTypes.contains(word))
type = _HighlightType.keyword;
else if (_firstLetterIsUpperCase(word))
type = _HighlightType.klass;
else if (word.length >= 2 && word.startsWith('k') && _firstLetterIsUpperCase(word.substring(1)))
type = _HighlightType.constant;
if (type != null) {
_spans.add(_HighlightSpan(
type,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
}
}
// Check if this loop did anything
if (lastLoopPosition == _scanner.position) {
// Failed to parse this file, abort gracefully
return false;
}
lastLoopPosition = _scanner.position;
}
_simplify();
return true;
}
void _simplify() {
for (int i = _spans.length - 2; i >= 0; i -= 1) {
if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) {
_spans[i] = _HighlightSpan(
_spans[i].type,
_spans[i].start,
_spans[i + 1].end
);
_spans.removeAt(i + 1);
}
}
}
bool _firstLetterIsUpperCase(String str) {
if (str.isNotEmpty) {
final String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
}
}
enum _HighlightType {
number,
comment,
keyword,
string,
punctuation,
klass,
constant
}
class _HighlightSpan {
_HighlightSpan(this.type, this.start, this.end);
final _HighlightType type;
final int start;
final int end;
String textForSpan(String src) {
return src.substring(start, end);
}
TextStyle textStyle(SyntaxHighlighterStyle style) {
if (type == _HighlightType.number)
return style.numberStyle;
else if (type == _HighlightType.comment)
return style.commentStyle;
else if (type == _HighlightType.keyword)
return style.keywordStyle;
else if (type == _HighlightType.string)
return style.stringStyle;
else if (type == _HighlightType.punctuation)
return style.punctuationStyle;
else if (type == _HighlightType.klass)
return style.classStyle;
else if (type == _HighlightType.constant)
return style.constantStyle;
else
return style.baseStyle;
}
}

19
lib/utils/net_utils.dart Normal file
View File

@ -0,0 +1,19 @@
import 'dart:async';
import 'package:dio/dio.dart';
var dio = new Dio();
class NetUtils {
static Future get(String url,{Map<String,dynamic> params}) async{
var response = await dio.get(url, data: params);
return response.data;
}
static Future post(String url,Map<String,dynamic> params) async{
var response = await dio.post(url, data: params);
return response.data;
}
}

93
lib/utils/provider.dart Normal file
View File

@ -0,0 +1,93 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:flutter/services.dart' show rootBundle;
//const createSql = {
// 'cat': """
// CREATE TABLE "cat" (
// `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
// `name` TEXT NOT NULL UNIQUE,
// `depth` INTEGER NOT NULL DEFAULT 1,
// `parentId` INTEGER NOT NULL,
// `desc` TEXT
// );
// """,
// 'collectio': """
// CREATE TABLE collection (id INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, router TEXT);
// """,
// 'widget': """
// CREATE TABLE widget (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, name TEXT NOT NULL, cnName TEXT NOT NULL, image TEXT NOT NULL, doc TEXT, demo TEXT, catId INTEGER NOT NULL REFERENCES cat (id), owner TEXT);
// """;
//};
class Provider {
static Database db;
// 获取数据库中所有的表
Future<List> getTables() async {
if (db == null) {
return Future.value([]);
}
List tables = await db.rawQuery('SELECT name FROM sqlite_master WHERE type = "table"');
List<String> targetList = [];
tables.forEach((item) {
targetList.add(item['name']);
});
return targetList;
}
// 检查数据库中, 表是否完整, 在部份android中, 会出现表丢失的情况
Future checkTableIsRight() async {
List<String> expectTables = ['cat', 'widget', 'collection'];
List<String> tables = await getTables();
for(int i = 0; i < expectTables.length; i++) {
if (!tables.contains(expectTables[i])) {
return false;
}
}
return true;
}
//初始化数据库
Future init(bool isCreate) async {
//Get a location using getDatabasesPath
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'flutter.db');
print(path);
try {
db = await openDatabase(path);
} catch (e) {
print("Error $e");
}
bool tableIsRight = await this.checkTableIsRight();
if (!tableIsRight) {
// 关闭上面打开的db否则无法执行open
db.close();
// Delete the database
await deleteDatabase(path);
ByteData data = await rootBundle.load(join("assets", "app.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes);
db = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
print('db created version is $version');
}, onOpen: (Database db) async {
print('new db opened');
});
} else {
print("Opening existing database");
}
}
}

Some files were not shown because too many files have changed in this diff Show More